Files
cmautobuy/client/test/test_pdd_page_classifier.py
T

109 lines
3.8 KiB
Python

"""PDD 页面分类与商品深链状态机测试。"""
from pathlib import Path
import unittest
import xml.etree.ElementTree as ET
from src.pdd_page_classifier import (
ACTION_NETWORK_ERROR,
ACTION_READY,
ACTION_REOPEN,
ACTION_UNAVAILABLE,
ACTION_WAIT,
PAGE_CAPTCHA,
PAGE_EXTERNAL,
PAGE_GOODS,
PAGE_HOME,
PAGE_LOADING,
PAGE_LOGIN_REQUIRED,
PAGE_NETWORK_ERROR,
PAGE_RISK_CONTROL,
GoodsOpenTracker,
classify_pdd_page,
)
FIXTURES = Path(__file__).parent / "fixtures"
PDD = "com.xunmeng.pinduoduo"
def observation(text: str, package: str = PDD):
xml = (
'<hierarchy><node package="{0}" class="android.widget.TextView" '
'text="{1}" bounds="[0,0][900,300]" visible-to-user="true"/>'
'<node package="{0}" text="占位一"/><node package="{0}" '
'text="占位二"/></hierarchy>'
).format(package, text)
return classify_pdd_page(ET.fromstring(xml), package)
class PddPageClassifierTest(unittest.TestCase):
def test_real_home_fixture_ignores_incorrect_focused_package(self) -> None:
root = ET.parse(FIXTURES / "pdd_home_page.xml").getroot()
result = classify_pdd_page(root, "com.android.settings")
self.assertEqual(PAGE_HOME, result.kind)
self.assertTrue(result.pdd_hierarchy)
def test_special_pages_are_not_home(self) -> None:
cases = {
"加载中": PAGE_LOADING,
"网络不给力": PAGE_NETWORK_ERROR,
"手机号登录": PAGE_LOGIN_REQUIRED,
"请完成验证": PAGE_CAPTCHA,
"操作频繁": PAGE_RISK_CONTROL,
"立即购买": PAGE_GOODS,
}
for label, expected in cases.items():
with self.subTest(label=label):
self.assertEqual(expected, observation(label).kind)
def test_browser_word_does_not_count_as_goods(self) -> None:
result = observation("立即购买", "com.android.chrome")
self.assertEqual(PAGE_EXTERNAL, result.kind)
def test_transient_home_can_reach_goods_without_reopen(self) -> None:
home = classify_pdd_page(
ET.parse(FIXTURES / "pdd_home_page.xml").getroot(), PDD
)
tracker = GoodsOpenTracker(None, 0.0)
self.assertEqual(ACTION_WAIT, tracker.observe(home, 2.0).action)
self.assertEqual(ACTION_WAIT, tracker.observe(home, 2.1).action)
self.assertEqual(
ACTION_READY, tracker.observe(observation("立即购买"), 2.2).action
)
def test_stable_home_reopens_once_then_marks_unavailable(self) -> None:
home = classify_pdd_page(
ET.parse(FIXTURES / "pdd_home_page.xml").getroot(), PDD
)
tracker = GoodsOpenTracker(None, 0.0)
for at in (2.0, 2.1):
self.assertEqual(ACTION_WAIT, tracker.observe(home, at).action)
self.assertEqual(ACTION_REOPEN, tracker.observe(home, 2.2).action)
tracker.reopened(3.0)
for at in (5.0, 5.1):
self.assertEqual(ACTION_WAIT, tracker.observe(home, at).action)
self.assertEqual(ACTION_UNAVAILABLE, tracker.observe(home, 5.2).action)
def test_old_goods_tree_is_not_accepted_as_new_target(self) -> None:
old = observation("旧商品标题 立即购买")
tracker = GoodsOpenTracker(old, 0.0)
self.assertEqual(ACTION_WAIT, tracker.observe(old, 0.2).action)
self.assertTrue(tracker.stale_goods_seen)
new = observation("目标商品标题 立即购买")
self.assertEqual(ACTION_READY, tracker.observe(new, 0.3).action)
def test_network_error_has_own_decision(self) -> None:
tracker = GoodsOpenTracker(None, 0.0)
decision = tracker.observe(observation("网络不给力"), 3.0)
self.assertEqual(ACTION_NETWORK_ERROR, decision.action)
if __name__ == "__main__":
unittest.main()