分离“;上下文”;以及“;触发器”;茉莉花
Separation of "context" and "trigger" in jasmine
假设我有一个简单的页面,点击页面标题可以切换页面内容的可见性(现实吗?不,但这是一个包含DOM元素的简单测试)。我将省去HTML和JS的实现,因为我相信您可以在脑海中看到它。
我正试图使用jasmine对此进行测试,但我遇到了代码重复问题,主要是围绕上下文的分离(该测试与bretheren的不同之处)和触发器(正在测试的操作和结果的捕获)
describe("Home", function () {
describe("Selecting the page title", function () {
beforeEach(function () {
loadFixtures('Home.fixture.htm');
});
describe("when page content is visible", function () {
it("should hide page content", function () {
$('#pageTitle').trigger('click');
expect($('#pageContent')).toBeHidden();
});
});
describe("when page content is hidden", function () {
it("should show page content", function () {
$('#pageContent').hide();
$('#pageTitle').trigger('click');
expect($('#pageContent')).toBeVisible();
});
});
});
});
如何将触发器(在这种情况下引发"点击")与上下文分离(共享=加载固定装置,特定=隐藏页面内容)以避免代码重复?
如果有帮助的话,下面是我在MSpec(.NET的上下文/规范框架)中要做的:
[Subject("Home")]
class when_selecting_the_page_title_when_page_content_is_visible : HomeContext
{
It should_hide_page_content = () =>
// Assert that page content is hidden
}
[Subject("Home")]
class when_selecting_the_page_title_when_page_content_is_hidden : HomeContext
{
Establish context = () =>
// Hide page content
It should_show_page_content = () =>
// Assert that page content is visible
}
class HomeContext
{
Establish context = () =>
// Load the fixture
Because of = () =>
// Fire the event
}
免责声明:我不想在这里争论C#与Javascript或MSpec与其他什么,它只是提供一个我想要的代码重用的例子。为了简化示例,我还跳过了MSpec的一些功能。
这就是为什么描述块可以嵌套,并且beforeEach()
可以在任何级别调用,只适用于该级别及以下级别。
我不会太担心测试中的代码重复。间接性越强,可读性越差。在合理的范围内,测试中的细节通常是一件好事。太多特定的宏函数只适用于代码的微小部分,你最终会得到一个巨大的脆性测试球,很少有人能想出如何更改。
describe("Home", function () {
describe("Selecting the page title", function () {
beforeEach(function () {
loadFixtures('Home.fixture.htm');
});
describe("when page content is visible", function () {
beforeEach(function() {
$('#pageTitle').trigger('click');
});
it("should hide page content", function () {
expect($('#pageContent')).toBeHidden();
});
});
describe("when page content is hidden", function () {
beforeEach(function() {
$('#pageContent').hide();
$('#pageTitle').trigger('click');
});
it("should show page content", function () {
expect($('#pageContent')).toBeVisible();
});
});
});
});
或者,如果必须的话,在描述块中设置一个辅助宏函数,但这可能会很快变得丑陋。它开始在你的测试中加入太多逻辑。最终,你的测试需要测试。哟,老兄。。。
describe("Home", function () {
describe("Selecting the page title", function () {
beforeEach(function () {
this.loadHomeFixture = function(options) {
options = options || {};
loadFixtures('Home.fixture.htm');
if (options.hidden) {
$('#pageContent').hide();
}
};
});
describe("when page content is visible", function () {
it("should hide page content", function () {
this.loadHomeFixture({ hidden: false });
expect($('#pageContent')).toBeHidden();
});
});
describe("when page content is hidden", function () {
it("should show page content", function () {
this.loadHomeFixture({ hidden: true });
expect($('#pageContent')).toBeVisible();
});
});
});
});
此外,有时我会先按状态组织测试,然后再按功能组织测试。允许您更干净地将初始状态与操作分离。
以下是如何在大纲形式中做到这一点。
- 主页
beforeEach: load home fixture
- 页面内容可见时
beforeEach: make content visible
- 选择页面标题
beforeEach: click page title
- 应隐藏页面内容
assert page content is hidden
- 当页面内容可见时执行的其他操作
- 页面内容隐藏时
beforeEach: make content hidden
- 选择页面标题
beforeEach: click page title
- 应显示页面内容
assert page content is visible
- 隐藏页面内容时执行的其他操作
这种结构允许您根据初始状态进行深入研究,因此,如果您有更多依赖于页面可见性的功能,则可以很容易地对这些功能进行测试,因为您已经有了状态设置,可以在其中放置新的测试。
虽然测试更像是一个矩阵(状态×特征),但大多数测试系统都给了我们一棵树。你是按状态还是按功能从树中分支,这在某种程度上取决于你,取决于哪个具有更高的复杂性。
- 迷你$provider注入茉莉花和角
- 悬停功能触发器
- 茉莉花宝石-耙茉莉花:ci dons't运行测试
- jQuery触发器点击未从AJAX成功工作
- 茉莉花节点测试;t正在运行
- 为什么会返回触发器('点击')
- 有没有一种方法可以检测ios<>使用jquery和触发器操作形成导航按钮
- jQuery自动完成触发器在选择时返回
- Meteor集成测试,在velocity'她的镜子上有茉莉花
- 用键盘分页jQuery下一个和上一个控件.触发器('点击')不'不起作用
- Meteor出版物'是这样的吗;t触发器
- JS触发器值检查在文档加载后添加到页面的元素在加载时更改AND
- jQuery触发器事件在一个循环中多次出现
- 如何在更新面板内部调用/触发javascript函数<触发器>标签
- 触发器方法在javascript对象中定义,但在对象本身之外
- API GET或Zapier触发器到POST操作
- AngularJS选择更改触发器
- 我可以把茉莉花规格报告器的输出写入文件吗
- 茉莉花 - 未调用方法
- 分离“;上下文”;以及“;触发器”;茉莉花