One of the many new features with Xcode 7 and Swift 2 is the
@testable attribute. While we have been able to do unit testing in
previous versions of Xcode and Swift the big drawback has always been that any
routine we wanted to test had to have an access level of public. This was a pretty big drawback especially with
frameworks where we need to test routines without making them public. This has changed in Xcode 7 and Swift 2. In this post we will demonstrate how to use
the new @testable attribute in our
test source code to make all public and internal routines usable by our test
code but not usable by other frameworks and app targets.
We will start off by creating a new project called Testability. When Xcode creates this project it will
create a module that is also named Testability. The following image shows the Testability
project that I created.
Now that we have our project, lets create a struct that we
can test. Lets name this struct TextValidation and put the following
code in it:
struct TextValidation {
let regExMatchingString = "^[\\s?[a-zA-Z0-9\\-]]{0,5}$"
func validateString(str: String) -> Bool {
if let _ = str.rangeOfString(regExMatchingString, options:
.RegularExpressionSearch) {
return true
} else {
return false
}
}
}
This TextValidation
struct sets a constant name regExMatchingString
to a regular expression string. This
regular expression is then used in the validateString
method to validate the string that is passed into the method. If the string matches the regular expresion,
the method returns true otherwise it
returns false.
Now lets create our test class. Right click on the TestabilityTests module
and select the New File option.
In the menu that pops up, select the Unit Test Case Class option.
This will create a standard unit test class with the basic code that we
need to get started. You can name the
class anything you wish but I like to name my test classes with a name that
describes what types of tests are in them.
In this case I named my class TextValidationTests.
When Xcode creates the new unit test class it creates it
with four functions. These are:
- setUp(): This method is called before each test is run. If we have four tests defined in our class and we ran all four tests then this setUp() method will be called four times (once before each test).
- tearDown(): This method is called after each test is run. If we have four tests defined in our class and we ran all four tests then this tearDown() method will be called four times (once after each test is run).
- testExample(): Sample test method, no code is actually in this method.
- testPerformanceExample(): Sample performance test method.
The last two methods (testExample()
and testPerformanceExample()
) can be safely deleted.
Now we need to use the @testable
attribute to import the module that we wish to test. In our case the module is the Testability module. Add the following line right below the Import XCTest line.
@testable import Testability
Now lets create a couple of tests. Add the following two method below the tearDown() method.
func testAgencyTrue()
{
let validation =
TextValidation()
XCTAssertTrue(validation.validateString("hel-o"))
}
func
testAgencyFalse() {
let validation = TextValidation()
XCTAssertFalse(validation.validateString("hel-o6"))
}
Now we can run the test by clicking on the little triangle
to the left of the class definition.
If everything tested correctly we should see little green
check boxes where the triangles use to be.
In this example we used the XCTAssertTrue() and XCTAssertFalse()
methods for our tests but there are a number of other XCTAssert methods that can
also be used. Here is a list of some of
the most useful tests:
Equality Tests:
XCTAssertEqual():
Generates a failure when two expressions are not equal.
XCTAssertNotEqual():
Generates a failure when two expressions are equal.
XCTAssertGreaterThan():
Generates a failure when the first expression is less than or equal to
the second.
XCTAssertGreaterThanOrEqual():
Generates a failure when the first expression is less than the second.
XCTAssertLessThan():
Generates a failure when the first expression is greater than or equal
to the second.
XCTAssertLessThanOrEqual():
Generates a failure when the first expression is greater than the
second.
Nil Tests
XCTAssertNil(): Generates
a failure when the expression is not nil.
XCTAssertNotNil():
Generates a failure when the expression is nil.
Boolean Tests
XCTAssertTrue():
Generates a failure when the expression evaluates to false.
XCTAssertFalse():
Generates a failure when the expression evaluates to true.
Unit testing can be incredible useful for projects that are going though continuous updates. With the new @testable attribute, Apple has eliminated the biggest hurdle that we had for adopting unit testing in our projects.
No comments:
Post a Comment