Skip to main content

参数化验证

参数化验证是什么

参数化验证,即指提供在多个 test cases 中重用相同测试逻辑的方法。

参数化验证要解决的问题

比如我们要测试下面的 emailValidator 函数:

export function emailValidator(email: string): boolean {
const regex = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
return regex.test(email);
}

很有可能就会写这样的测试代码:

describe("emailValidator", () => {
it("should return true for a valid email", () => {
const email = "valid-email@example.com";
expect(emailValidator(email)).toBe(true);
});

it("should return false for a invalid email without domain extension", () => {
const email = "valid-email@example";
expect(emailValidator(email)).toBe(false);
});

it("should return false for a invalid email with extra dot at the end", () => {
const email = "valid-email@example.";
expect(emailValidator(email)).toBe(false);
});

it("should return false for a invalid email with missing '@'", () => {
const email = "valid-email.example.com";
expect(emailValidator(email)).toBe(false);
});

// ... ...
});

上面所有的 test cases 都是一样的逻辑,只是输入输出不一样。

使用参数化验证

参数化验证 - 数组

这个时候,就可以使用 vitest 提供的 it.each API 来处理:

describe("emailValidator", () => {
it.each([
["valid-email@example.com", true],
["valid-email@example", false],
["valid-email@example.", false],
["valid-email.example.com", false],
])("should return %s when validating %s", (email, excepted) => {
expect(emailValidator(email).toBe(excepted));
});
});

注意,为了快速定位失败的测试用例,一定要使用占位符来写描述信息。

占位符:

%s - String. %d - Number (both integer and float). %j - JSON. %% - single percent sign ('%'). This does not consume an argument.

参数化验证 - 对象 :thumbsup:

describe("emailValidator", () => {
it.each([
{ email: "valid-email@example.com", expected: true },
{ email: "valid-email@example", expected: false },
{ email: "valid-email@example.", expected: false },
{ email: "valid-email.example.com", expected: false },
])(
"should return $email when validating $expected",
({ email, excepted }) => {
expect(emailValidator(email).toBe(excepted));
}
);
});

如果是用对象来构建输入输出,那占位符可以使用 $parameter 的形式。

使用对象的方式可读性更高。

参数化验证 - 模板标签

describe("emailValidator", () => {
it.each`
"email" | "expected"
${"valid-email@example.com"} | ${true}
${"valid-email@example"} | ${false}
${"valid-email@example."} | ${false}
${"valid-email.example.com"} | ${false}
`("should return $email when validating $expected", ({ email, excepted }) => {
expect(emailValidator(email).toBe(excepted));
});
});