单元测试¶
概述¶
我们在活动流中的单元测试使用 mocha、chai 和 sinon 编写,并使用 karma 运行。它们包括内容代码(React 组件等)和 .sys.mjs
的单元测试。
您可以在 tests/unit
中找到单元测试。
执行¶
要运行一次单元测试,请执行 npm test
。
要持续运行单元测试(即在“测试驱动开发”模式下),您可以运行 npm run tddmc
。
调试¶
要调试测试,您应该使用 npm run tddmc
以持续模式运行它们。在打开的 Firefox 窗口中(它应该显示“Karma… - connected”),点击“debug”按钮并打开您的控制台以查看测试输出、设置断点等。
不幸的是,Firefox 中的测试源映射目前尚不可用。如果您需要查看行号,可以通过运行 npm install --save-dev karma-chrome-launcher && npm run tddmc -- --browsers Chrome
使用 Chrome 运行测试。
放置新测试的位置¶
如果您正在创建新的测试,请将其添加到 tests/unit
的子目录中,该子目录对应于您正在测试的文件。测试应以 .test.js
或 .test.jsx
结尾,如果测试包含任何 jsx。
例如,如果您正在测试的文件是 lib/Foo.sys.mjs
,则测试文件应为 test/unit/lib/Foo.test.js
Mocha 测试¶
我们所有的单元测试都是使用 mocha 编写的,它注入诸如 describe
、it
、beforeEach
等全局变量。它可用于编写同步或异步测试。
describe("FooModule", () => {
// A synchronous test
it("should create an instance", () => {
assert.instanceOf(new FooModule(), FooModule);
});
describe("#meaningOfLife", () => {
// An asynchronous test
it("should eventually get the meaning of life", async () => {
const foo = new FooModule();
const result = await foo.meaningOfLife();
assert.equal(result, 42);
});
});
});
断言¶
要编写断言,请使用全局可用的 assert
对象(这是由 karma-chai 提供的,因此您无需 require
它)。
例如
assert.equal(foo, 3);
assert.propertyVal(someObj, "foo", 3);
assert.calledOnce(someStub);
您可以使用来自以下任何断言:
自定义断言¶
我们有一些自定义断言用于检查各种类型的操作。
.isUserEventAction(action)
¶
断言给定的 action
是有效的用户事件,即它仅包含活动流中用户事件的预期/有效属性。
// This will pass
assert.isUserEventAction(ac.UserEvent({event: "CLICK"}));
// This will fail
assert.isUserEventAction({type: "FOO"});
// This will fail because BLOOP is not a valid event type
assert.isUserEventAction(ac.UserEvent({event: "BLOOP"}));
在 .sys.mjs
中覆盖全局变量¶
您将要测试的大多数 .sys.mjs
使用 Cu.import
或 XPCOMUtils
来注入全局变量。为了为这些全局变量添加模拟/存根/伪造,您应该使用 test/unit/utils
中的 GlobalOverrider
实用程序。
const {GlobalOverrider} = require("test/unit/utils");
describe("MyModule", () => {
let globals;
let sandbox;
beforeEach(() => {
globals = new GlobalOverrider();
sandbox = globals.sandbox; // this is a sinon sandbox
// This will inject a "AboutNewTab" global before each test
globals.set("AboutNewTab", {override: sandbox.stub()});
});
// globals.restore() clears any globals you added as well as the sinon sandbox
afterEach(() => globals.restore());
});
测试 React 组件¶
您应该使用 enzyme 测试套件来测试活动流的 React 组件。
如果可能,请使用 浅渲染方法(这将避免不必要地渲染子组件)。
const React = require("react");
const {shallow} = require("enzyme");
describe("<Foo>", () => {
it("should be hidden by default", () => {
const wrapper = shallow(<Foo />);
assert.isTrue(wrapper.find(".wrapper").props().hidden);
});
});
如果需要,您也可以使用 enzyme 的 mount
实用程序进行 完整 DOM 渲染。
const React = require("react");
const {mount} = require("enzyme");
...
const wrapper = mount(<Foo />);