chai - 如何(以及是否)修改Chai BDD链中的对象

标签 chai

我正在使用ChaiJS插件使用Casper-Chai,但不确定如何解决遇到的特定问题。

我希望能够编写如下测试:

expect(casper).selector("#waldo").to.be.visible;

这非常简单,例如
utils.addChainableMethod(chai.Assertion.prototype, 'selector', 
  selectorMethod, selectorChainableMethod);

utils.addMethod(chai.Assertion.prototype, 'visible', visibleMethod);
*Method引用涉及执行相应测试或可链接调用的函数。

我的问题是拥有例如“选择器”修改链中的后代。我想到两个选择:
  • 使用utils.flag(chai, 'object')将其更改为选择器;或
  • 使用例如utils.flag(chai, 'casper-selector')

  • 调用“visible”时,它可以读取相应的标志。修改``对象''似乎有用的地方是在调用例如“长度”稍后。但是,我有点担心更改“对象”的意外副作用。

    我可能还想修改对象,以便进行“长度”测试,例如:
    // there can be only one!
    expect(casper).selector("#waldo").length(1)
    
    // but that one has 4 classes
    expect(casper).selector("#waldo").class.to.have.length(4)
    

    感谢您的任何想法和投入。

    ---- 编辑 ----

    好的,这是植根于Casper-Chai的概念挑战,它需要对Casper是什么以及为什么Casper-Chai应该是Chai插件而不是现有Casper API的替代品进行一些描述。 Casper是PhantomJS无头Web浏览器的包装,因此,Casper可有效运行两个不同的虚拟机:A
    “ Controller ”和无头Web浏览器。

    Controller 中没有DOM或“文档”或“窗口”对象;尽管使用WebKit javascript解析器,但Controller在这方面与Node.js非常相似。同时,PhantomJS启动了无头Web浏览器。然后, Controller 可以通过PhantomJS / Casper API与无头浏览器进行通信。 Controller可以告诉无头浏览器加载哪些页面,运行什么javascript(就像在控制台中键入javascript),甚至模拟事件,例如键盘输入和鼠标单击。无头浏览器具有完整的DOM和JavaScript堆栈:它是WebKit中加载的网页。您可以capture screenshots WebKit将呈现的内容。

    Casper-Chai在Controller中运行。在Controller的Mocha + Chai中创建的测试旨在根据无头浏览器的状态进行评估。尽管我们可以将状态从浏览器复制到Controller并在复制的状态上运行测试,但是我对该设计的有限实验揭示了该设计固有的问题(即效率,竞争条件,性能和潜在的副作用)。问题在于浏览器状态是动态的,复杂的,并且可能笨拙。

    因此,以约翰为例,由于没有DOM,因此expect(casper.find("#waldo")).to.be.visible将不起作用,除非Casper返回的对象进行了某种惰性的评估/中介。即使我们序列化并复制了HTML元素,Controller中也没有CSS。然后,即使#waldo拥有CSS,也无法像浏览器一样测试层次结构。我们必须复制DOM的大部分内容和所有CSS,然后复制一个Web浏览器以测试#waldo是否可见-对于每个测试。 Casper-Chai旨在通过在浏览器中运行测试来避免此问题。

    仅需要一点点额外的照明,一个简单的比较就是获得与选择器匹配的元素数量。可以编写expect(casper.evaluate(function () {return __utils__.findAll('.my_class')}).to.have.length(4),其中casper.evaluate在无头浏览器中运行给定的函数,并以字符串形式返回与选择器匹配的DOM元素列表;您可以将__utils__视为Casper的jQuery版本。或者,可以编写expect(casper).selector('.my_class').to.have.length(4),其中selector成为“对象”,并且它具有调用“casper.evaluate(function(){return utils .findAll('。my_class')。length”的 setter/getter .length。仅整数长度对于少量的测试,它们都可以正常工作,但是对于大量的测试,此性能特征会产生影响(此处以这种简单的形式出现,在更复杂的情况下可能会更大程度地发挥作用)。

    当然可以写expect(casper.evaluate(function () { __utils__.findAll('.my_class').length }).equal(4),但是如果要编写这样的测试,为什么还要麻烦BDD / Chai?它消除了Chai提供的可读性的好处。

    还值得注意的是,Controller中可能有多个Casper实例,对应于多个PhantomJS页面。将它们视为怪异的标签。

    因此,根据Domenic的回答,修改'object'标志是解决该问题的适当方法,这似乎是最实用的方法-鉴于以上描述,应考虑任何想法。

    我希望以上内容描述了为什么Casper-Chai应该是插件,而不仅仅是Casper的API扩展。我还将由Casper的作者运行此命令,以查看他是否有任何输入。

    这可能不是一个完美的关系,但我希望Casper&Chai能够和睦相处。 :)

    最佳答案

    困难源于casper具有高度程序化的API(使用Casper#click(String selector)Casper#fetchText(String selector)之类的方法)的事实。为了自然地适应chai,需要一个面向对象的API,例如Casper#find(String selector)(返回CasperSelection对象),CasperSelection#click()CasperSelection#text()等。

    因此,我建议您使用findselector方法extend the casper object itself,它返回一个可以作为断言基础的对象。然后,您将不需要更改对象标志。

    expect(casper.find("#waldo")).to.be.visible;
    expect(casper.find("#waldo")).to.have.length(1)
    expect(casper.find("#waldo").class).to.have.length(4)
    

    关于chai - 如何(以及是否)修改Chai BDD链中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13999229/

    相关文章:

    node.js - Mocha + Chai 命令行退出,错误代码编号等于测试失败计数

    javascript - Mocha 和 NightmareJS-继续测试

    javascript - 使用 Mocha 测试 Promise

    javascript - 在我的 Django 应用程序中对 javascript 函数进行单元测试

    postman - 如何在 Postman 中标记测试

    node.js - 将自定义 http header 添加到 chai 请求

    node.js - 使用 Chai.js 检查 json 对象中的 'http://' 文本

    node.js - Nodejs、moch/chai 在 macOS 上失败并显示 "Segmentation fault: 11"

    javascript - Mocha 测试超时

    javascript - Mocha 测试相同对象的assert.equal 失败