Files
2026-07-13 12:29:17 +08:00

137 lines
3.5 KiB
Python

"""extract.py 的单元测试。用合成样本(不提交真实指标)。
跑:python test_extract.py
"""
from extract import _to_int, parse_post_meta, parse_post_summary
# 合成样本:复刻真实 /analytics/post-summary/ 的 inner_text 版式(日文界面),数字是假的。
POST_SAMPLE_JP = """Heqing Huangさんが投稿しました • 4日
post body line one
post body line two with a stray number 123 inside
調査
9,999
インプレッション数
800
リーチしたメンバー
プロフィールアクティビティ
5
この投稿からのプロフィール閲覧ユーザー
2
この投稿で獲得したフォロワー
エンゲージメント
30
ソーシャルエンゲージメント
リアクション
20
コメント
6
再投稿
3
保存数
1
LinkedInでの送信数
0
上位統計データ
"""
# 英文界面(LinkedIn 随机切换)。
POST_SAMPLE_EN = """Heqing Huang posted this • 6d
post body text with stray number 999
Discovery
50,000
Impressions
30,000
Members reached
Profile activity
400
Profile viewers from this post
180
Followers gained from this post
Engagement
300
Social engagements
Reactions
100
Comments
25
Reposts
8
Saves
100
Sends on LinkedIn
67
Top demographics
"""
def test_to_int():
assert _to_int("34,057") == 34057
assert _to_int("152") == 152
assert _to_int("1.2K") == 1200
assert _to_int("3M") == 3_000_000
assert _to_int("n/a") is None
def test_parse_post_summary_jp():
m = parse_post_summary(POST_SAMPLE_JP)["metrics"]
assert m["impressions"] == 9999, m
assert m["reach"] == 800, m
assert m["profile_views_from_post"] == 5, m
assert m["followers_from_post"] == 2, m
assert m["social_engagement"] == 30, m
assert m["reactions"] == 20, m
assert m["comments"] == 6, m
assert m["reposts"] == 3, m
assert m["saves"] == 1, m
assert m["sends"] == 0, m
def test_parse_post_summary_en():
m = parse_post_summary(POST_SAMPLE_EN)["metrics"]
assert m["impressions"] == 50000, m
assert m["reach"] == 30000, m
assert m["profile_views_from_post"] == 400, m
assert m["followers_from_post"] == 180, m
assert m["social_engagement"] == 300, m
assert m["reactions"] == 100, m
assert m["comments"] == 25, m
assert m["reposts"] == 8, m
assert m["saves"] == 100, m
assert m["sends"] == 67, m
def test_parse_post_summary_missing_is_none():
assert parse_post_summary("no metrics here")["metrics"]["impressions"] is None
def test_parse_post_meta_jp():
meta = parse_post_meta(POST_SAMPLE_JP)
assert meta["author"] == "Heqing Huang", meta
assert meta["age"] == "4日", meta
assert "post body line one" in meta["text"], meta
assert "post body line two" in meta["text"], meta
# 正文不应吃进指标小标题 / 指标
assert "調査" not in meta["text"], meta
assert "インプレッション数" not in meta["text"], meta
def test_parse_post_meta_en():
meta = parse_post_meta(POST_SAMPLE_EN)
assert meta["author"] == "Heqing Huang", meta
assert meta["age"] == "6d", meta
assert "post body text" in meta["text"], meta
assert "Discovery" not in meta["text"], meta
def test_parse_post_meta_missing():
meta = parse_post_meta("no byline at all\njust text")
assert meta == {"author": "", "age": "", "text": ""}, meta
if __name__ == "__main__":
fns = [v for k, v in sorted(globals().items()) if k.startswith("test_") and callable(v)]
for fn in fns:
fn()
print(f"✓ {fn.__name__}")
print(f"\n{len(fns)} passed")