2012-08-01 32 views
3

假设我有一个简单的页面,点击页面标题可以切换页面内容的可见性(真实吗?否,但它是一个包含DOM元素的简单测试)。我会告诉你HTML和JS的实现,因为我确信你可以在你的脑海中看到它。茉莉花中的“上下文”和“触发器”的分离

我试图用茉莉花来测试这个,我正在运行代码重复问题,主要是围绕上下文的分离(这个测试如何与它的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#VS Javascript或MSpec VS任何这里,它只是提供了我之后的代码重用示例。我也跳过了MSpec的一些功能,以保持示例简单。

回答

4

那么这就是为什么描述块可以嵌套,并且beforeEach()可以在只适用于该级别下的任何级别调用。

我不会过分担心测试中的代码重复。更间接意味着更少的可读性。在合理的范围内,测试中的详细程度通常是件好事。太多的特定的宏函数只适用于你的代码的小部分,你最终会遇到一个巨大的脆弱测试球,很少有人可以找出如何改变。或者,如果必须,在该描述块中设置一个助手宏函数,但这可能会变得很难看。它开始在你的测试中放入太多的逻辑。最终你需要测试你的测试。哟dawg ...

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
      • 其他的行动,做一些事情时,页面内容被隐藏

此结构允许您基于初始状态进行钻取,因此如果您有更多功能依赖于页面上的可见性,则很容易测试这些功能,因为您已经有了可以放置该状态设置的位置新的测试。

虽然测试可能更像矩阵(状态×功能),但大多数测试系统给我们一棵树。无论你是按状态还是按功能分支树,都取决于你,取决于哪一个具有更高的复杂性。