【问题标题】:How to get intellij to offer a text diff comparison on failed tests如何让 intellij 对失败的测试提供文本差异比较
【发布时间】:2015-03-28 15:54:12
【问题描述】:

我正在使用一些 ScalaTest 匹配器编写 Scala 测试。

当我的测试失败时,intellij 会说类似

{"count":3,"pagination":{"offset":0,"limit":100},"content":{"uri":"http://locahost.com/catalogue/content?order=Query&id=18,20,19"},"list":[{"id":"18","position":27},{"id":"20","position":341},{"id":"19","position":33}]} was not equal to {"count":3,"pagination":{"offset":0,"limit":100},"content":{"uri":"http://locahost.com/catalogue/content?order=Query&id=18,20,19"},"list":[{"id":"18","timestamp":"2015-01-28T11:55:44.494Z","content":"Episode","position":27},{"id":"20","timestamp":"2015-01-19T11:55:44.494Z","content":"Program","position":341},{"id":"19","timestamp":"2015-01-17T11:55:44.494Z","content":"Episode","position":33}]}
org.scalatest.exceptions.TestFailedException: {"count":3,"pagination":{"offset":0,"limit":100},"content":{"uri":"http://locahost.com/catalogue/content?order=Query&id=18,20,19"},"list":[{"id":"18","position":27},{"id":"20","position":341},{"id":"19","position":33}]} was not equal to {"count":3,"pagination":{"offset":0,"limit":100},"content":{"uri":"http://locahost.com/catalogue/content?order=Query&id=18,20,19"},"list":[{"id":"18","timestamp":"2015-01-28T11:55:44.494Z","content":"Episode","position":27},{"id":"20","timestamp":"2015-01-19T11:55:44.494Z","content":"Program","position":341},{"id":"19","timestamp":"2015-01-17T11:55:44.494Z","content":"Episode","position":33}]}
at    org.scalatest.MatchersHelper$.newTestFailedException(MatchersHelper.scala:160)
at org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(Matchers.scala:6231)
at org.scalatest.Matchers$AnyShouldWrapper.should(Matchers.scala:6265)
...

但是,intellij 并没有让我方便地看到文本功能的差异。

我认为这可能是因为我正在比较 2 个对象

  val responseBody = responseAs[JsValue]
  responseBody should be(viewingByAccountIdResponseJson)

但将其更改为

assert(responseBody.toString() === viewingByAccountIdResponseJson.toString())

也不允许我进行文本比较。

有没有办法配置 intellij 来做到这一点?

(我目前正在使用带有 Matchers 的 FlatSpec)

注意:这与这个问题有关 Formatting output so that Intellij Idea shows diffs for two texts

但是,即使使用推荐的 intellij 可能会采用的语法,它也不起作用。

【问题讨论】:

  • 如果我使用 assert(x === y)x should be (y) 比较两个字符串 xy,则使用 Idea 14.0.2、ScalaTest 2.2.1 和 Scala 2.11.4 我看到 "a[bc]de" did not equal "a[BC]de"认为是你想要的行为。您确定没有妨碍您的特殊配置吗?或者,也许您只是在使用旧版本的 ScalaTest?我相信无论如何它只适用于字符串。
  • 它是否为您提供了比较两个突出显示差异的文本的链接?我发现使用 java+groovy 可以做到这一点,只是不在我的 Scala 测试中。这意味着比较 json 字符串,找出不同之处是一个相当大的挑战。
  • 不,它没有。你有任何理由相信 ScalaTest 会在 IntelliJ 的上下文之外做到这一点吗?

标签: scala intellij-idea scalatest intellij-14


【解决方案1】:

我认为目前这是不可能的,并且就目前而言,这是一个功能请求:

https://youtrack.jetbrains.com/issue/SCL-4867

【讨论】:

  • 这里的问题是,当 IntelliJ 看到输出时,完整的预期文本和完整的实际文本已被剥离。
【解决方案2】:

随着布鲁斯提到的intellij feature request 庆祝它的 7 岁生日,我们中的一些人已经失去了希望(仍然不要忘记 +1)。这是一个丑陋的脚本,可让您稍微减轻问题。只需复制 This was not equal to That 行并将其提供给此脚本的标准输入:

| scalatest-diff
cat > ~/bin/scalatest-diff
#!/usr/bin/perl

my $in = join("", <STDIN>);
if( $in =~ m/[^:]+\: (.+?) was not equal to (.+)/so ) {
    my $this = $1;
    my $that = $2;
    $this =~ s/,/,\n/g;
    $that =~ s/,/,\n/g;
    open(thisFile, ">", "/tmp/this");
    open(thatFile, ">", "/tmp/that");
    print thisFile $this; close thisFile;
    print thatFile $that; close thatFile;
    exec("vimdiff /tmp/this /tmp/that");
}
<Ctrl-D>
chmod a+x ~/bin/scalatest-diff

附:随意将 vimdiff 更改为您最喜欢的不同。

【讨论】:

    【解决方案3】:

    问题在于 ScalaTest 在显示差异之前试图很好地格式化左右对象。

    您可以通过定义自己的匹配器来解决这个问题,该匹配器会抛出一个不那么花哨的TestFailedException。以下是如何在基于匹配器的测试中实现这一点的草图:

    
      it must "show diff" in {
        """Hello
          |World!
          |""".stripMargin shouldEqualPlainly
          ("""Hello
             |ScalaTest.
             |""".stripMargin)
      }
    
      implicit class PlainEquality[T](leftSideValue: T) {
        // Like should equal, but does not try to mark diffs in strings with square brackets,
        // so that IntelliJ can show a proper diff.
        def shouldEqualPlainly(right: Any)(implicit equality: Equality[T]): Assertion =
          if (!equality.areEqual(leftSideValue, right)) {
            throw new TestFailedException(
              (e: StackDepthException) => Some(s"""${leftSideValue} did not equal ${right}"""),
              None,
              Position.here
            )
          } else Succeeded
      }
    
    

    这会让你点击并给你这样的东西:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-03
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      相关资源
      最近更新 更多