Skip to content

[Tests] Inline expectations and substitute [[@LINE]] numbers #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

modocache
Copy link
Contributor

  1. Enhance xctest_checker such that it can parse "CHECK" prefixes that are in the middle of a line (instead of just at the very beginning). This allows us to inline the test expectations.
  2. Enhance xctest_checker such that it substitutes the string "[[@line]]" with the current line number of the source file when performing checks. This mirrors the behavior of FileCheck (although that program also handles "[[@line+]]").
  3. Inline all checks in the suite, and replace all hardcoded and regex line numbers in the functional test suite with the new substitution.

This allows us to add and remove arbitary lines in the functional test suite without manually updating line numbers! 💯

For example, the old tests looked like this:

// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' started.
// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:19: error: ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: foo
// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' failed \(\d+\.\d+ seconds\).
func test_waitingForAnUnfulfilledExpectation_fails() {
    waitForExpectationsWithTimeout(0.2, handler: nil)
}

The new tests look like this (notice we don't hardcode the line number "19"):

func test_waitingForAnUnfulfilledExpectation_fails() { // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' started.
    expectationWithDescription("foo")
    waitForExpectationsWithTimeout(0.2, handler: nil) // CHECK: .*/Asynchronous/Expectations/main.swift:[[@LINE]]: error: ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: foo
} // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' failed \(\d+\.\d+ seconds\).

@modocache modocache force-pushed the functional-test-improvements branch from c2c529c to e1c8d6a Compare March 10, 2016 04:11
@briancroom
Copy link
Contributor

This looks really helpful! Nice Python-fu.

@briancroom
Copy link
Contributor

While the line number substitution is unquestionably a maintainability win, I'm concerned that these changes harm the test legibility a bit. Because the // CHECK: lines aren't lined up anymore, it gets a lot more difficult for my eye to know where to look to start trying to parse the line contents, I'm finding. It starts looking more like an unstructured wall of text. (Possibly relevant - do you have line-wrapping enabled in your editor?)

I'd be interested to hear how others feel about how this effects test readability!

@mike-ferris
Copy link

Would supporting [[@line-1]] and/or [[@line+1]] help? I agree that having the comment strain the actual content of the line makes for long lines.

@modocache
Copy link
Contributor Author

Hmm, interesting. I don't have line-wrapping enabled, and I must admit I do have to do a lot of side scrolling to see the expected text. So I can see where you two are coming from.

I'll try adding support for LINE+, like FileCheck has.

@modocache modocache force-pushed the functional-test-improvements branch 4 times, most recently from dc94501 to 34b7dd2 Compare March 13, 2016 01:45
@modocache
Copy link
Contributor Author

@briancroom @mike-ferris-apple OK, the expectations are no longer inlined, and instead use offsets like [[@LINE+3]]. This allows us to add and remove arbitary lines in the functional test suite without manually updating line numbers in most cases. Line offsets will still need to be updated when the distance between the CHECK and the test failure changes--for example:

diff --git a/Tests/Functional/FailureMessagesTestCase/main.swift b/Tests/Functional/FailureMessagesTestCase/main.swift
index 1f7e4f6..3c50ff1 100644
--- a/Tests/Functional/FailureMessagesTestCase/main.swift
+++ b/Tests/Functional/FailureMessagesTestCase/main.swift
@@ -158,9 +158,10 @@ class FailureMessagesTestCase: XCTestCase {
     }

     // CHECK: Test Case 'FailureMessagesTestCase.testFail' started.
-    // CHECK: test.swift:[[@LINE+3]]: error: FailureMessagesTestCase.testFail : failed - message
+    // CHECK: test.swift:[[@LINE+4]]: error: FailureMessagesTestCase.testFail : failed - message
     // CHECK: Test Case 'FailureMessagesTestCase.testFail' failed \(\d+\.\d+ seconds\).
     func testFail() {
+        // Adding this comment forces me to update the [[@LINE]] offset
         XCTFail("message", file: "test.swift")
     }

I think this makes it much easier to write tests!

Rather than manually inserting the program name and default option
values into the help text, use the `%(prog)s` and `%(default)s`
substitutions built into argparse.
1. Enhance xctest_checker such that it can parse "CHECK" prefixes that
   are in the middle of a line (instead of just at the very beginning).
2. Indent and move the "CHECK"s in the functional test suite to match their
   surroundings, or otherwise make them more readable.

These changes make it much easier to understand what source code lines
are tied to what output. It also makes it easier to keep line numbers
in sync (although this is still a manual process for now).
1. Enhance xctest_checker such that it substitutes the string "[[@line]]"
   and "[[@line+<offset>]]" with the current line number of the source file
   when performing checks.
2. Replace all hardcoded and regex line numbers in the functional test
   suite with the new substitution.

This allows us to add and remove arbitary lines in the functional test
suite without manually updating line numbers in most cases. Line
offsets will still need to be updated when the distance between the
CHECK and the test failure changes.
@modocache
Copy link
Contributor Author

I'm closing this to eliminate some noise on this repository's pull requests. The spiritual successor to this pull request is #94. As @briancroom mentions in that discussion, it's probably best to migrate all of this over to LLVM FileCheck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants