【问题标题】:Print message on expect() assert failure在 expect() 断言失败时打印消息
【发布时间】:2014-04-23 18:00:31
【问题描述】:

有没有办法在 Jasmine expect() 失败时打印自定义错误消息?

例如,对于端到端测试,我有一组网页,我使用一个测试转到每个 URL 并断言每个页面上都存在一个元素。我知道我可以将每个 expect() 放入单独的测试中,但我宁愿遍历数组并在失败时记录页面 URL。

【问题讨论】:

    标签: javascript testing jasmine protractor


    【解决方案1】:

    更新

    我看到人们仍在寻找这个。 Jasmine 团队后来提供的信息是,expect 中有一个未记录的功能 - 您可以包含自定义失败消息,它就可以正常工作:

    expect( fields[i].element.exists() ).toEqual(true, field[i].name + ' is expected to exist');
    

    这正是我最初想要的。

    原答案如下

    我今天一直在寻找这个,并在这里发表评论:https://github.com/adobe/brackets/issues/2752

    已经讨论过的语法是对 Jasmine 的扩展,允许添加因为 - 所以你可以这样写:

    expect( fields[i].element.exists() ).toEqual(true).because( field[i].name + 'is expected to exist');
    

    几年后仍在讨论中,可能不会实现。我发现的另一种方法是创建自定义匹配器。一般来说,我认为我会劝阻自定义匹配器,但不能确保您使用它覆盖所有基础,但在这种情况下,我们实际上是在检查真/假值,所以匹配器并不太可怕。

    我们可以使用 beforeEach 创建自定义匹配器:

    beforeEach(function() {
      var matchers = {
        toEqualBecause: function( value, message ) {
          this.message = function() {
            return "Expected '" + this.actual + "' to equal '" + value + "' because " + message;  
          };
    
          return this.actual == value;  
        }
     };
    
      this.addMatchers(matchers);
    });
    

    然后我们可以使用这个匹配器来发送一条带有我们失败的消息:

    expect( field[i].element.exists() ).toEqualBecause( true, field[i].name );
    

    这将给出包括字段名称在内的失败输出:

    Expected 'false' to equal 'true' because account_name
    

    【讨论】:

    • 很棒的发现! expect(something).toBeFalsy('不应该……');也有效
    • 嗨!当然,您应该将您的最新发现放在您的答案之上,这样就可以直接访问它(将其余部分保留为下面的历史日志)。谢谢。
    • 从 jasmine 3.3.0 开始,它似乎适用于 toBe,但不适用于 toEqual
    • 仍然无法使用 toEqual,尽管它已记录在案。使用toBe,您可以测试在对象上失败的完全相同的值(可能是因为原型部分)所以仍然不适用:(
    • 我认为这“仍在讨论中”很荒谬。这是测试框架的一个明显特征,从一开始就是这样。感谢您展示解决方法。
    【解决方案2】:

    是的,我们可以在 Jasmine 中的 expect() 失败时打印自定义错误消息。

     Code Snippet:
    
      it('print a custom error message when an expect failed', function() {
    
        var elemenToBeDisplayed=element(by.css("userName"));
    
        /*custom error message will be displayed if expected condition 
        failed*/
    
        expect(elemenToBeDisplayed.isPresent).toBe(true,'Write your custom       
             error message here');
       });
    

    【讨论】:

    • 虽然此语法当前有效,但未记录在案,应谨慎使用。
    • 不错。同样的技巧似乎不适用于toEqual。有什么解决办法吗?
    • @Suresh Salloju 它没有 =\
    • @StavAlfi 什么?
    【解决方案3】:

    Jasmine 3.3 包含 withContext 作为官方支持的方式来指定有关期望的附加信息,而无需担心您使用的是哪个匹配器。

    【讨论】:

    • 嘿,@HolgerJeromin,我正在使用 jasmine 3.3.1,我写了expect(true).withContext("reason").toBe(false);,我得到了Failed: expect(...).withContext is not a function。任何想法为什么会发生?
    • @SergeyPleshakov 我使用 Jasmine 3.3.0 并获得预期结果:reason: Expected true to be false.
    【解决方案4】:

    从 Jasmine 3.3 开始,有一种方法可以通过 withContext 来实现

    例子:

    expect(someValue).withContext('expected someValue to be true...').toBe(true)
    

    另见https://github.com/jasmine/jasmine/issues/641#issuecomment-457037665

    【讨论】:

    • 嘿,@ernstjan,我正在使用 jasmine 3.3.1,我写了expect(true).withContext("reason").toBe(false);,我得到了Failed: expect(...).withContext is not a function。任何想法为什么会发生?
    【解决方案5】:

    您可以使用fail() 方法来做到这一点。

    it('should fail with a message', function() {    
      if (!foo) fail(`your message here`);
    });
    

    【讨论】:

      【解决方案6】:

      其他答案解释了如何破解“期望”,但还有另一种方法可以解决您的问题,尽管它需要您稍微改变一下思路。与其将“期望”视为您的测试行为,不如将单个“it”调用下的所有期望视为您的测试行为。

      我遇到此问题最多的情况是,当我有一个正在执行某种密集解析的函数并且我想编写 20 个几乎相同的测试时。

      像这样安排你的输入和输出:

      var testDatas = [
        {
          input: 'stringtoparse1',
          output: 'String To Parse 1'
        },
        {
          input: 'stringtoparse2',
          output: 'String To Parse 2'
        },
        {
          input: 'stringtoparse3',
          output: 'String To Parse 3'
        },
      ];
      

      现在遍历您的测试数据列表,并从 inside 循环中调用“它”,如下所示:

      testDatas.forEach(function(test) {
        it('should parse for input ' + test.input, function() {
          expect(myParser(test.input).toEqual(test.output);
        });
      });
      

      您可以减少在测试中飞来飞去的无关代码的数量,并且可以为每个期望或一组期望格式化一条消息。

      【讨论】:

      • 哇,我想知道测试运行程序如何计算类似这样的测试数量,并发现使用 for 循环(在 Visual Studio 中使用 Chutzpah 测试运行程序和 Jasmine)将所有迭代添加为单独测试到测试资源管理器!
      【解决方案7】:

      我需要为 Jasmine 记录自定义消息,我使用了以下方法。

      beforeEach(function(){
          this.addMatchers({
              customError: function(mesg){
                               this.message= function () {
                                                 return mesg;
                                             };
                               return this.actual == true;
                               }
                           });
              });
      if(<fail condidtion>){
          expect(false).customError(<Fail message>)
      }
      

      请注意,我上面提到的是 jasmine 1 格式。如果你使用 jasmine 2,会有轻微的变化。 希望对你有帮助

      【讨论】:

        【解决方案8】:

        示例: 我需要在第一次加载时验证页面的颜色。

        expect(obj.color).toBe(true, 10000, 'Custom Message');
        

        未来:

        • true - 预期为 True,
        • 10000 - 等待时间
        • 自定义消息(根据我们的要求,我们可以在日志报告中写入消息/错误)

        【讨论】:

          【解决方案9】:

          这是我在 Jasmine 2.6.4 中使用的 TypeScript(Visual Studio 中的 Jasmine+Chutzpah)。

          通过 NuGet 的最新 Jasmine 版本似乎是 2.6.4,所以我没有“withContext”的东西(它也似乎有点笨拙,我更喜欢在最后标记一条消息像许多其他框架一样的匹配器)。

          即使“expectationFailOutput”参数(要显示的消息)出现在 jasmine.d.ts 分型中,它似乎也没有得到 jasmine 的官方支持:

          然而,非正式地,它似乎对除 toEqual 匹配器之外的所有对象都有效。

          我使用以下内容在全局范围内添加了一个新的 toBeEqualTo 匹配器,我从原始 toEqual 匹配器复制了该匹配器,并将expectationFailOutput 消息添加到末尾。接口声明位允许我们使用 expect(...).toBeEqualTo(...) 而不用 TypeScript 抱怨。

          示例用法:

          expect(x).toBe(y, "Some Message"); // stock message works with .toBe
          expect(x).toEqual(y, "This is ignored"); // stock message ignored with .toEqual
          expect(x).toBeEqualTo(y, "My message is displayed"); // new matcher added below
          

          TypeScript 实现:

          /// <reference path="../../Scripts/typings/jasmine/jasmine.d.ts"/>
          
          declare namespace jasmine
          {
              interface Matchers
              {
                  toBeEqualTo(expected: any, expectationFailOutput?: any): boolean;
              }
          }
          
          beforeEach(function ()
          {
              jasmine.addMatchers(<any>{
                  toBeEqualTo: function (util, customEqualityTesters)
                  {
                      customEqualityTesters = customEqualityTesters || [];
          
                      return {
                          compare: function (actual, expected, expectationFailOutput)
                          {
                              var diffBuilder = (<any>jasmine).DiffBuilder();
          
                              return {
                                  pass: util.equals(actual, expected, customEqualityTesters, diffBuilder),
          
                                  message: diffBuilder.getMessage() + ": " + expectationFailOutput
                              };
                          }
                      };
                  }
              });
          });
          

          【讨论】:

          • 你在 DiffBuilder 中有什么?量角器的茉莉不认识它。
          • 不知道 - 我只是从原始 .toEqual 复制代码并添加了失败消息。对我来说,它适用于 VS/Chutzpah。你可能有一个 TypeScript 类型错误 - 这就是我强制转换为 的原因,否则 TypeScript 会说 DiffBuilder not found。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-17
          • 1970-01-01
          • 2011-10-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多