为啥在 Quick 的单元测试中多次调用 before- 和 afterEach 块?

Posted

技术标签:

【中文标题】为啥在 Quick 的单元测试中多次调用 before- 和 afterEach 块?【英文标题】:Why are the before- and afterEach blocks called multiple times in unit-testing with Quick?为什么在 Quick 的单元测试中多次调用 before- 和 afterEach 块? 【发布时间】:2017-05-18 09:52:54 【问题描述】:

我用一些示例组编写了一个测试用例,包括beforeEachafterEach。 我预计每个beforeEachafterEach 都会为每个it 调用一次。

唉,对于单个 itbeforeEachafterEach 被多次调用。

我查看了一些文档(即 Quick 自己的文档和 http://jasmine.github.io/2.1/introduction.html),但这些对我的事业没有帮助。

这里有一个小 sn-p 演示了这一点:

类 CheckerTests: QuickSpec

override func spec() 

    describe("something") 
        beforeEach 
            tLog.info("describe before")
        
        afterEach 
            tLog.info("describe after")
        

        context("of something") 
            beforeEach 
                tLog.info("context before")
            
            afterEach 
                tLog.info("context after")
            

            it("should behave like something") 
                tLog.info("in the `IT`")
                expect(true).to(beTrue())
            
        
    



我的控制台日志:

以上日志提出了两个问题:

我不确定 什么时候 beforeEachafterEach 现在被调用;我也不知道为什么我看到多个日志调用它们。怎么会被多次调用?

- 以上日志显示context的后块被调用之前示例通过...不应该发生之后em> 例子?

从我的代码 sn-p 我希望日志返回:

有人能解释一下这里发生了什么吗?这是正确的行为吗?


编辑:

根据评论的建议;我还在it 示例中添加了一个日志inside(参见上面的修改后的代码 sn-p)。 这给了我以下日志:

Test Suite 'CheckerTests' started at 2017-05-18 13:35:29.025
Test Case '-[CheckerTests something__of_something__should_behave_like_something]' started.
13:35:29.046 ???? INFO CheckerTests.spec():21 - describe before
13:35:29.046 ???? INFO CheckerTests.spec():21 - describe before
13:35:29.048 ???? INFO CheckerTests.spec():29 - context before
13:35:29.048 ???? INFO CheckerTests.spec():29 - context before
13:35:29.048 ???? INFO CheckerTests.spec():36 - in the `IT`
13:35:29.048 ???? INFO CheckerTests.spec():36 - in the `IT`
13:35:29.049 ???? INFO CheckerTests.spec():32 - context after
1Test Case '-[CheckerTests something__of_something__should_behave_like_something]' passed (0.024 seconds).
3:35:29.049 ???? INFO CheckerTests.spec():32 - context after
13:35:29.050 ???? INFOTest Suite 'CheckerTests' passed at 2017-05-18 13:35:29.050.
     Executed 1 test, with 0 failures (0 unexpected) in 0.024 (0.025) seconds
 CheckerTests.spec():24 - describe after
13:35:29.050 \360\237\222Test Suite 'CheckerTests.xctest' passed at 2017-05-18 13:35:29.051.
     Executed 1 test, with 0 failures (0 unexpected) in 0.024 (0.026) seconds
\231 INFO CheckerTests.spec():24 - describe after
Test Suite 'Selected tests' passed at 2017-05-18 13:35:29.051.
     Executed 1 test, with 0 failures (0 unexpected) in 0.024 (0.029) seconds

上面的日志显示该示例运行了两次,这让我更加困惑。


编辑: 回答了其中一个问题:

- 以上日志显示context的后块被调用之前示例通过...不应该发生之后em> 例子?

似乎测试以正确的顺序跟进,因此回答了上述问题。


编辑:

供参考;这就是我的 Podfile 的样子:

def pods_for_testing
    pod 'Quick'
    pod 'Nimble'
    pod 'KIF'
end

target 'Checker' do
  project 'Checker.xcodeproj', 'dev' => :debug, 'ntrl' => :debug, 'acpt' => :release, 'prod' => :release, 'prod appstore' => :release

  pod 'SQLCipher'
  pod 'UrbanAirship-ios-SDK'
  pod 'TBXML', :inhibit_warnings => true
  pod 'SSZipArchive'
  pod 'Google/Analytics'
  pod 'Moya', '>= 8.0'
  pod 'Unbox'
  pod 'ProcedureKit'
  pod 'ProcedureKit/Mobile'
  pod 'SwiftyBeaver'
  pod 'OHHTTPStubs'
  pod 'OHHTTPStubs/Swift'

  target 'CheckerTests' do
      inherit! :search_paths
      pods_for_testing
  end

  target 'CheckerUITests' do
      inherit! :search_paths
      pods_for_testing
  end

end

除此之外,我不确定还有哪些其他设置可能会影响测试。

【问题讨论】:

如果在it 中添加print("test print"),它什么时候打印?测试库在清理后打印有关测试通过的信息这一事实对我来说似乎很好。 如果我在it 中使用打印inside 调整测试,打印结果也会打印两次。似乎it 被调用了两次或什么的。 所以从这个测试并形成您的编辑,我们知道这些方法以正确的顺序执行 - 事实上,测试通过的信息打印在context after 之后是无关紧要的。现在,唯一剩下的问题是方法执行了两次。 我已经更新了问题;事实仍然是该示例执行了多次... 你确定这个方法被执行了两次并且不仅仅是一个日志条目被打印了两次吗?也许添加一个变量来计算对方法的调用? 【参考方案1】:

我试图重现该问题。但就我而言,每个测试用例都被准确地执行了一个。

因此,该问题在正常设置中似乎无法重现。可能您有一些特殊设置导致上述问题。

注意: 我不确定您还需要哪些其他库来获取“tLog.info”,但我找不到。我认为这对这个目的无关紧要。我用 print(_:) 语句代替。

这是我的“TryQuickTest.swift”的样子:

import XCTest
import Quick
import Nimble 

class TryQuickTest: QuickSpec 

    override func spec() 

        describe("blah") 
            beforeEach 
                print("describe before")
            
            afterEach 
                print("describe after")
            

            context("of blah2") 
                beforeEach 
                    print("context before")
                
                afterEach 
                    print("context after")
                

                it("first it should be like this") 
                    print("in the first `IT`")
                    XCTFail("Hey fail in first it")
                

                it("second it should be like this") 
                    print("in the second `IT`")
                    XCTFail("Hey fail in second it")
                
            
           
        

以及运行此测试文件的控制台:

Test Suite 'Selected tests' started at 2017-05-28 07:35:32.345
Test Suite 'PlayQuickTests.xctest' started at 2017-05-28 07:35:32.347
Test Suite 'TryQuickTest' started at 2017-05-28 07:35:32.348
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this]' started.
describe before
context before
in the first `IT`
/Users/shisui/Developer/General/iOS_Swift/PlayQuick/PlayQuickTests/TryQuickTest.swift:35: error: -[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this] : failed - Hey fail in first it
context after
describe after
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this]' failed (0.004 seconds).
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__second_it_should_be_like_this]' started.
describe before
context before
in the second `IT`
/Users/shisui/Developer/General/iOS_Swift/PlayQuick/PlayQuickTests/TryQuickTest.swift:40: error: -[PlayQuickTests.TryQuickTest blah__of_blah2__second_it_should_be_like_this] : failed - Hey fail in second it
context after
describe after
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__second_it_should_be_like_this]' failed (0.003 seconds).
Test Suite 'TryQuickTest' failed at 2017-05-28 07:35:32.359.
    Executed 2 tests, with 2 failures (0 unexpected) in 0.007 (0.010) seconds
Test Suite 'PlayQuickTests.xctest' failed at 2017-05-28 07:35:32.359.
    Executed 2 tests, with 2 failures (0 unexpected) in 0.007 (0.012) seconds
Test Suite 'Selected tests' failed at 2017-05-28 07:35:32.374.
    Executed 2 tests, with 2 failures (0 unexpected) in 0.007 (0.029) seconds

从上面的输出。每个测试用例只执行一次。

如果我删除第二个“它”部分。控制台输出如下所示:

Test Suite 'Selected tests' started at 2017-05-28 07:56:09.214
Test Suite 'PlayQuickTests.xctest' started at 2017-05-28 07:56:09.215
Test Suite 'TryQuickTest' started at 2017-05-28 07:56:09.215
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this]' started.
describe before
context before
in the first `IT`
/Users/shisui/Developer/General/iOS_Swift/PlayQuick/PlayQuickTests/TryQuickTest.swift:35: error: -[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this] : failed - Hey fail in first it
context after
describe after
Test Case '-[PlayQuickTests.TryQuickTest blah__of_blah2__first_it_should_be_like_this]' failed (0.006 seconds).
Test Suite 'TryQuickTest' failed at 2017-05-28 07:56:09.222.
    Executed 1 test, with 1 failure (0 unexpected) in 0.006 (0.007) seconds
Test Suite 'PlayQuickTests.xctest' failed at 2017-05-28 07:56:09.224.
    Executed 1 test, with 1 failure (0 unexpected) in 0.006 (0.009) seconds
Test Suite 'Selected tests' failed at 2017-05-28 07:56:09.224.
    Executed 1 test, with 1 failure (0 unexpected) in 0.006 (0.011) seconds

【讨论】:

我建议从头开始创建一个新项目并再次添加快速框架。可能跟一些特殊设置有关。 新建了一个项目,再试一次;第一次有同样的问题,第二次我得到了正确的输出。我真的不知道为什么。我不确定在我的测试(在原始项目中)中可以有什么特殊设置,我使用了相同的 pod 和配置。 哦,供参考; tLog 只是我的“测试记录器”,SwiftyBeaver 的一个实例 啊,看看通知。说实话,我仍然不知道为什么会这样。然而,让赏金“浪费”也是……浪费:) 仅供参考。我在 SO 中提出了一个关于如何在 Xcode 上可靠地设置快速测试框架的新问题。 ***.com/q/44244912/3549695

以上是关于为啥在 Quick 的单元测试中多次调用 before- 和 afterEach 块?的主要内容,如果未能解决你的问题,请参考以下文章

quick + nimble 单元测试

如何使用不同的方法多次模拟调用 AWS 服务的 Golang 函数的单元测试?

Qt Quick 的单元测试

IOS为啥对一个类调用ViewController进行单元测试

如何创建 Qt-Quick 测试

如何防止在 dart 中使用 expectAsync 的单元测试进展?