来源说明:本文参考 Uberi 的 Yunit 项目和官方文档整理。Yunit 是一个面向 AutoHotkey 的轻量测试框架,可用于自动化代码测试、基准测试、结果输出和测试管理。本文结合本站 AI 写的 AHK 代码怎么验收,讲它在 AHKv1 脚本里的实际用法。
很多 AHK 脚本平时靠“运行一下看起来没报错”来验收。小脚本问题不大,但一旦开始写函数库、自动办公、网络请求、字符串处理、路径处理,靠肉眼点几下就不够了。Yunit 的价值是:把你认为必须成立的结果写成测试,让脚本自己帮你反复检查。
一、Yunit 适合测什么
Yunit 最适合测试纯逻辑和可重复结果,例如:
- 字符串处理函数。
- 路径拼接函数。
- JSON/CSV 数据转换。
- 时间、数字、数组、对象处理。
- AI 生成的工具函数是否符合预期。
它不太适合直接测试“鼠标有没有点到某个窗口”“某个按钮颜色是否变化”这种强依赖外部环境的内容。GUI 和窗口自动化也能测,但要做更多准备,初学者先从函数测试开始。
二、最小测试结构
Yunit 的基本用法是:引入 Yunit,选择输出模块,然后把测试类交给 Test()。测试类里的方法就是测试项;正常结束就是通过,抛出异常就是失败。最常用的是 Yunit.Assert()。
#Requires AutoHotkey v1.1
#NoEnv
#SingleInstance Force
#Include %A_ScriptDir%\Lib\Yunit\Yunit.ahk
#Include %A_ScriptDir%\Lib\Yunit\Window.ahk
Yunit.Use(YunitWindow).Test(TestString)
return
class TestString
{
TrimText()
{
result := Trim(" AHK ")
Yunit.Assert(result = "AHK", "Trim 后应该得到 AHK")
}
SplitCount()
{
arr := StrSplit("a,b,c", ",")
Yunit.Assert(arr.Length() = 3, "应该拆出 3 个元素")
}
}
官方文档里提到,测试方法不需要参数,也不需要返回值。只要测试方法正常跑完,就算通过;如果 Assert 失败,会抛出异常并记录失败信息。
三、目录怎么放
Yunit 文档建议把 Yunit 文件夹放进项目的库路径里。AHKv1 常见库搜索顺序包括脚本目录下的 Lib、用户文档目录下的 Lib、以及 AutoHotkey 安装目录下的 Lib。
SomeProject |-- Lib | |-- Yunit | | |-- Yunit.ahk | | |-- Window.ahk | | |-- Stdout.ahk | | |-- OutputDebug.ahk | | |-- JUnit.ahk |-- MyLib.ahk |-- MyLib_Test.ahk
如果你只是自己用,放在当前项目 Lib 里最清楚,不容易和别的项目版本冲突。
四、输出模块怎么选
Yunit 有多个输出模块。新手建议先用 YunitWindow,因为它会用窗口显示测试结果,最直观。
YunitWindow:窗口显示结果,适合本机手动运行。YunitStdout:输出到标准输出,适合命令行和自动化脚本。YunitOutputDebug:输出到调试器,适合配合 DebugView 等工具。YunitJUnit:生成 JUnit XML,适合 CI 或更正式的测试流程。
; 同时使用窗口和标准输出 Yunit.Use(YunitWindow, YunitStdout).Test(TestString, TestPath)
五、测试类和分类
Yunit 用 class 组织测试。类里的方法是测试项,嵌套类可以作为分类。这样你的测试文件不会很快变成一堆散乱函数。
class TestPath
{
JoinBasic()
{
path := JoinPath("C:\Test", "a.txt")
Yunit.Assert(path = "C:\Test\a.txt", "路径拼接错误")
}
class FileName
{
Extension()
{
ext := GetExt("demo.ahk")
Yunit.Assert(ext = "ahk", "扩展名应该是 ahk")
}
}
}
测试名称来自类名和方法名,所以建议命名清楚。不要写 Test1、Test2,过一周你自己也不知道它在测什么。
六、Begin 和 End:每个测试前后准备环境
官方文档里提到,特殊方法 Begin() 和 End() 会在每个测试前后调用。它适合准备临时变量、创建测试文件、清理环境。
class TestTempFile
{
Begin()
{
this.file := A_Temp "\ahk_test.txt"
FileDelete, % this.file
}
WriteRead()
{
FileAppend, hello, % this.file, UTF-8
FileRead, text, % this.file
Yunit.Assert(text = "hello", "写入后读出的内容不一致")
}
End()
{
FileDelete, % this.file
}
}
这样测试之间互不影响。不要让一个测试依赖另一个测试先运行,因为测试调用顺序不应该成为脚本正确性的前提。
七、用 Yunit 验收 AI 写的 AHK
AI 写 AHK 最容易出现的问题是:看起来很像对,但边界条件没处理。比如路径最后有没有反斜杠、空字符串怎么办、中文编码怎么办、数组下标从 1 开始还是 0 开始。这些问题特别适合写成测试。
class TestAiFunction
{
EmptyInput()
{
Yunit.Assert(NormalizeName("") = "", "空输入应该返回空")
}
ChineseText()
{
Yunit.Assert(NormalizeName("脚本 测试") = "脚本_测试", "中文空格替换失败")
}
KeepExtension()
{
Yunit.Assert(NormalizeName("demo.ahk") = "demo.ahk", "不应该破坏扩展名")
}
}
你不需要一开始就写很多测试。最实用的做法是:每次发现一个 bug,就把它写成一个测试。这样同类问题以后不会反复回来。
八、哪些东西不适合一开始就测
不建议新手一上来就用 Yunit 测复杂 GUI、游戏窗口、剪贴板、浏览器页面、管理员权限窗口。这些场景受环境影响大,写测试会很繁琐。
更好的路线是:
- 把核心逻辑拆成函数。
- 先测试函数。
- 窗口、鼠标、键盘、权限等部分用人工验收清单。
- 重要脚本再逐步加入日志和自动检查。

评论(0)