913b0c9ca7
覆盖 detect_card_rows 行检测、count_blue_pixels 蓝勾检测、 sample_rgb_from_file 像素采样、std_profile 标准差剖面、 date_label_hash/screenshot_hash 哈希稳定性。全部通过。
154 lines
5.2 KiB
Python
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()
|