title: Swift: Unit tests with functions that throw
body: <p>How can one write unit tests in Swift that communicate useful information  when calling functions that can throw?</p>
  
  <p>What I'd really like to be able to do is something like this:</p>
  
  <pre><code>class TestTestsTests: XCTestCase {
  
      func doFoo() throws -&gt; String {
          // A complex operation that might throw in various places
          return "foo"
      }
  
      func doBar() throws -&gt; String {
          // A complex operation that might throw in various places
          return "bar"
      }
  
      func testExample() throws {
          let foo = try doFoo()
          let bar = try doBar()
          XCTAssertNotEqual(foo, bar)
      }
  
  }
  </code></pre>
  
  <p>Ideally the unit test runner would stop on the line where an unhandled exception occurred, and let the user explore the stack and error message. Unfortunately, adding <code>throws</code> to the test function causes it to be silently skipped over (and there's a UI bug that makes it look as though the test is still being run, and getting the same result as before adding <code>throws</code>).</p>
  
  <p>Of course it is also possible to do this:</p>
  
  <pre><code>func testExample() {
      let foo = try! doFoo()
      let bar = try! doBar()
      XCTAssertNotEqual(foo, bar)
  }
  </code></pre>
  
  <p>But now a failure doesn't really provide the context we need. Add a <code>throw</code> to <code>doFoo</code>, and we get a message like <code>fatal error: 'try!' expression unexpectedly raised an error: TestTestsTests.Error(): file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.1.101.15/src/swift/stdlib/public/core/ErrorType.swift, line 50</code>, which only gives us the line number within <code>testExample</code>, and not within <code>doFoo</code> where the error occurred. This also seems to get the debugger 'stuck' (clicking continue just returns us to the same line with the same error message) on that line, regardless of whether breakpoints are enabled, and prevents other tests from running.</p>
  
  <p>So maybe we could try something like this?</p>
  
  <pre><code>func testExample() {
      do {
          let foo = try doFoo()
          let bar = try doBar()
          XCTAssertNotEqual(foo, bar)
      } catch {
          XCTFail("\(error)")
      }
  }
  </code></pre>
  
  <p>This runs as expected, however we can't determine which of <code>doFoo</code> or <code>doBar</code> threw the error, and also no line number information. At least we can get the error message and not prevent other tests from running.</p>
  
  <p>I could go on, but the short of it is that I can't find a way to simultaneously not break the unit test running (like with <code>try!</code>), figure out which function threw the error, and get the error information -- Unless I do something ridiculous like:</p>
  
  <pre><code>func testExample() {
      var foo: String? = nil
      var bar: String? = nil
      do {
          foo = try doFoo()
      } catch {
          XCTFail("\(error)")
          return
      }
      do {
          bar = try doBar()
      } catch {
          XCTFail("\(error)")
          return
      }
  
      if let foo = foo, bar = bar {
          XCTAssertNotEqual(foo, bar)
      }
  }
  </code></pre>
  
  <p>And I still don't get to find out where in <code>doFoo</code> or <code>doBar</code> the error occurred.</p>
  
  <p>Is this just the sad state of unit testing in Swift, or am I missing something?</p>