13

How to stop unit test execution if a logic is failed. Below is the example. How to stop execution when XCTAssertEqual("Hello", "Hi", "Passed") condition is failed.

func test_one() 
{    
    XCTAssertEqual("Hello", "Hi", "Passed")    
    let b = "Good Morning!" 
    // code continues...
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Coder
  • 1,661
  • 4
  • 27
  • 50
  • You should only have one assert per test, and it should be the last line in your test, so this really is a problem with your code structure, which again means a good answer can't really be provided for your problem. – Claus Jørgensen Aug 05 '15 at 19:39
  • 1
    I will be difficult if we are testing a parsing logic. What I mean is I have a service response, I have to parse the data and store it in database. I have to test if the parsing of the response is proper. Obviously i will have entire parsing logic in a single function, and so there will be multiple assert conditions.. please correct me if i am wrong – Coder Aug 05 '15 at 19:49
  • No, you can just do a common setup, and have individual asserts in each test. Multiple asserts means you don't know why the test failed without reading the logs in details, which is breaks the idea of fast feedback – Claus Jørgensen Aug 05 '15 at 19:51
  • While I certainly agree that tests should not test too much, that does not mean there should only be 1 assert per test. Ex. Testing the "add" method of an array. You might want to check that add returns true for successfully adding and that the count increased by one. Ex 2. If a block returns that has an error and a response, you will want to assert that the error is nil and the response is "x" value – Kevin Aug 05 '15 at 19:53
  • You can still write that as two tests. And if you written your tests good, it's just 1 extra line aside from the function declaration in the first place. I'll recommend reading http://osherove.com/blog/2005/4/14/try-to-avoid-multiple-asserts-in-a-single-unit-test.html – Claus Jørgensen Aug 05 '15 at 19:59
  • I think the idea of one assert per test seems very unrealistic. You would end up with 1000s of tests with tens of thousands of lines of identical code - or a complex subclassing structure. With continueAfterFailure set to false the test stops anyway after one asset fails and with a message on each assert so you can go directly to the one that is failing. Once the test is passing, it can be ignored - unless regression causes it to fail again. The overhead of duplicating and managing such a huge additional codebase would be a significant drag. So what is the benefit of this rule? – Alan Mar 01 '19 at 07:47
  • @ClausJørgensen, the link you pointed to does not apply to Swift, since all of the asserts in a test method are executed, you don't get only the first 'symptom' (as the blog post names them). Furthermore, related asserts are going to fail together in a single method so it's easier to make the connection. (Having said that, what the OP asks and the answer provided defeat that mechanism, I agree on that. But sometimes, you just want to fail fast) – Victor Jalencas Mar 30 '20 at 13:51

1 Answers1

37

XCTestCase has a variable var continueAfterFailure: Bool which defaults to true. This means that the test continues running even after a test fails

override func setUp() {
    super.setUp()
    // Put setup code here. This method is called before the invocation of each test method in the class.
    continueAfterFailure = false
}
Kevin
  • 16,696
  • 7
  • 51
  • 68
  • 1
    Thanks Kevin. Can I use this continueAfterFailure in between 2 assert conditions. As mentioned in my question, if the XCTAssert 1 condition is failed, XCTAssert 2 condition should not be executed. – Coder Aug 05 '15 at 19:57
  • 1
    That is what will happen when you set continuedAfterFailure to false – Kevin Aug 05 '15 at 20:02
  • Awesome! did not know about this! – Sajjon Nov 20 '17 at 14:19