Files
yuming 913b0c9ca7 test: 新增automate.py Pillow图像函数回归测试(9个用例)
覆盖 detect_card_rows 行检测、count_blue_pixels 蓝勾检测、
sample_rgb_from_file 像素采样、std_profile 标准差剖面、
date_label_hash/screenshot_hash 哈希稳定性。全部通过。
2026-09-18 16:13:22 +08:00

154 lines
5.2 KiB
Python

"""automate.py 的 Pillow 图像分析函数回归测试。
覆盖:detect_card_rows 行检测、count_blue_pixels 蓝勾检测、
sample_rgb_from_file 像素采样、std_profile 标准差剖面、
date_label_hash / screenshot_hash 哈希稳定性。
这些测试用合成图片验证逻辑,不需要启动模拟器。
"""
import os
import random
import tempfile
import unittest
from PIL import Image, ImageDraw
# 把项目根目录加入 path
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import automate
class TestDetectCardRows(unittest.TestCase):
def test_detects_three_rows(self):
img = Image.new("RGB", (1080, 2400), (240, 240, 240))
random.seed(42)
for row_top in [1060, 1280, 1500]:
for y in range(row_top, row_top + 180):
for x in range(100, 980):
img.putpixel((x, y), (
random.randint(50, 200),
random.randint(50, 200),
random.randint(50, 200),
))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
rows = automate.detect_card_rows(path)
self.assertEqual(len(rows), 3)
for expected, actual in zip([1150, 1370, 1590], rows):
self.assertLess(abs(expected - actual), 20)
finally:
os.unlink(path)
def test_empty_image_returns_no_rows(self):
img = Image.new("RGB", (1080, 2400), (200, 200, 200))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
rows = automate.detect_card_rows(path)
self.assertEqual(rows, [])
finally:
os.unlink(path)
class TestCountBluePixels(unittest.TestCase):
def test_blue_badge_detected(self):
img = Image.new("RGB", (1080, 2400), (200, 200, 200))
draw = ImageDraw.Draw(img)
draw.rectangle([500, 1160, 580, 1240], fill=(100, 143, 252))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
cnt = automate.count_blue_pixels(path, 540, 1200)
self.assertGreaterEqual(cnt, 500)
finally:
os.unlink(path)
def test_gray_area_not_detected(self):
img = Image.new("RGB", (1080, 2400), (200, 200, 200))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
cnt = automate.count_blue_pixels(path, 200, 1200)
self.assertLess(cnt, 500)
finally:
os.unlink(path)
class TestSampleRgb(unittest.TestCase):
def test_sample_pixel(self):
img = Image.new("RGB", (100, 100), (0, 0, 0))
img.putpixel((50, 50), (255, 128, 64))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
rgb = automate.sample_rgb_from_file(path, 50, 50)
self.assertEqual(rgb, (255, 128, 64))
finally:
os.unlink(path)
def test_out_of_bounds_returns_zero(self):
img = Image.new("RGB", (10, 10), (10, 20, 30))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
rgb = automate.sample_rgb_from_file(path, 999, 999)
self.assertEqual(rgb, (0, 0, 0))
finally:
os.unlink(path)
class TestStdProfile(unittest.TestCase):
def test_textured_rows_have_high_std(self):
img = Image.new("RGB", (1080, 2400), (240, 240, 240))
random.seed(123)
for y in range(1100, 1300):
for x in range(350, 1050):
img.putpixel((x, y), (random.randint(0, 255),) * 3)
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
prof = automate.std_profile(path)
textured = sum(1 for _, s in prof if s >= 28)
self.assertGreater(textured, 100)
finally:
os.unlink(path)
class TestHashStability(unittest.TestCase):
def test_date_label_hash_stable(self):
img = Image.new("RGB", (1080, 2400), (100, 150, 200))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
h1 = automate.date_label_hash(path)
h2 = automate.date_label_hash(path)
self.assertEqual(h1, h2)
finally:
os.unlink(path)
def test_screenshot_hash_stable(self):
img = Image.new("RGB", (1080, 2400), (100, 150, 200))
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
path = f.name
try:
img.save(path)
h1 = automate.screenshot_hash(path)
h2 = automate.screenshot_hash(path)
self.assertEqual(h1, h2)
finally:
os.unlink(path)
if __name__ == "__main__":
unittest.main()