[IOS translation] iOS7 by Tutorials series: using unit testing in Xcode 5 (below)

Source: Internet
Author: User

4. debugging of test failure

It is time to track the previous test failure issues. Open GameBoard. m. Find the cellStateAtColumn: andRow: And setCellState: forColumn: andRow: methods. You will see that they call a helper method called checkBoundsForColumn: andRow: To detect the array boundary.

Header fileGameBoard. hThe methods in are described as follows:

// raises an NSRangeException if the column or row are out of bounds

However, if the checkBoundsForColumn: andRow: method implementation throws an NSGenericExpression. Generally, you treat the comment in the header file as a public API specification, but the code and specification in this example do not match. What should you do?

One possibility is to update comments and related tests to match the current implementation. In this example, the comment in the Specification looks more meaningful: a boundary check should follow NSArray and raise a nsangeexception.

 

Update checkBoundsForColumn: andRow in GameBoard. m: The implementation of the method is as follows:

- (void)checkBoundsForColumn:(NSInteger)column andRow:(NSInteger)row{if (column < 0 || column > 7 || row < 0 || row > 7)[NSException raise:NSRangeExceptionformat:@"row or column out of bounds"];}

Run the test again. All tests should pass.

Since the code is not synchronized, there is always a risk in the annotations. However, you can add double insurance for annotations in your test. Since you write the test code, as long as you run the test frequently, the risk of mismatched implementations will be greatly reduced!

In addition, your test provides a great high-level overview Code, especially after following the suggested naming rules. After you re-enter the code that you haven't touched for a long time, it will be very convenient-as in the next section.

 

5. Ensure testing bugs

A crash report just entered your app: One Of Your testers reported you. When she runs the game, she directly clicks the screen (without clicking the "2 Player" or "vs computer" button ), the program will crash.

If you try it on your own, you will see the following information on the console:

ReversiGame[1842:a0b] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'row or column out of bounds'

The crash seems to happen again. What throws a nsangeexception? Call stack provides the following information:

2 CoreFoundation +[NSException raise:format:] + 1393 ReversiGame -[GameBoard checkBoundsForColumn:andRow:] + 142 4 ReversiGame -[GameBoard cellStateAtColumn:andRow:] + 765 ReversiGame -[ReversiBoard flipOpponentCountersForColumn: andRow:withNavigationFunction:toState:] + 2816 ReversiGame -[ReversiBoard makeMoveToColumn:andRow:] + 245 7 ReversiGame -[BoardSquare cellTapped:] + 192

Read from bottom up:

7th and 6 lines of tap trigger code are used to process players' movements

5th-Line Game logic checks whether opponent's pawns are surrounded and flipped

4th and 3 lines of code and then call cellStateAtColumn: andRow: and

CheckBoundsForColumn: andRow:

The underlying framework of Row 3 reports an out-of-bounds exception.

 

Want to know more about debugging crashes? Here

My App Crashed, Now What?http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1Demystifying iOS Application Crash Logshttp://www.raywenderlich.com/23704/demystifying-ios-application-crash-logs

This is a great opportunity to test these crash conditions.

Your new test should not only fix this problem, but also be used as a regression test to ensure that this bug remains fixed. Nothing is more uncomfortable than encountering the same bug when adding new features or refactoring code months after fixing a bug.

 

6. Determine what needs to be tested

You know you need to test-but what should you test?

ReversiBoard is a common implementation of the GameBoard class, so it makes sense to start troubleshooting from here.

 

UseIOS \ Cocoa Touch \ Objective-C test case classCreate a new class namedReversiBoardTestsInherited from XCtestCase.

Before you start, delete the testExample method of the template file, and thenReversiBoardsTests. mImport header files:

#import "ReversiBoard.h"

 

InReversiBoardsTests. mChange @ interface as follows:

@interface ReversiBoardTests : XCTestCase { ReversiBoard *_reversiBoard;}

Adding a _ reversiBoard instance variable means you do not have to instantiate it repeatedly in each test method.

Then, modify the setUp method as follows:

- (void)setUp {[super setUp];_reversiBoard = [[ReversiBoard alloc] init];}

 

7. Test rejection

In the tests written earlier, exceptions exist as expected. This time, the exception did not appear on the basis of your test.

Add these methodsReversiBoardsTests. m

- (void)test_makeMove_inPreGameState_nothingHappens {[_reversiBoard setToPreGameState];XCTAssertNoThrowSpecificNamed([_reversiBoard makeMoveToColumn:3 andRow:3],NSException,NSRangeException,@"Making a move in the pre-game state should do nothing");}

In the above Code, test and set the status before the game. That is to say, the status of the player before the player chooses to play against AI or other players. This test simulates the click Board action as soon as you enter the game.

XCTAssertNoThrowSpecificNamed assertions are the opposite of XCTAssertThrowsSpecificNamed. If the specified exception is thrown, the above test will fail; if the specified exception is not thrown, the test will pass.

You have not fixed the bug, so running the code now will fail-but this is a good thing. Writing a test before fixing the bug means you have the ability to reproduce the bug.

 

Command + URun the test and you will see the following information:

test failure: -[ReversiBoardTests test_makeMove_inPreGameState_nothingHappens] failed: (([_reversiBoard makeMoveToColumn:3 andRow:3]) does not throw <NSException, "NSRangeException">) failed

 

8. Correction Code

OpenReversiBoard. mThen find the makeMoveToColumn: andRow: method.

Think about how to fix this particular bug. It makes sense to move the game only after you select the game mode. In this case, there is no difference between the game logic before and after the game.

Fortunately, here is an attribute that specifies the current game status: gameState.

 

Add the following code to makeMoveToColumn: andRow: Top Of The method:

if ([self gameState] != GameStateOn) return;

This condition detects the current game status. If the status is not GameStateOn, the game is not running. The method is to terminate immediately.

Run the app and test whether to crash by clicking the chessboard before selecting the game mode?

 

Finally,Command + URun the Test. The Test Navigator should display a green tick and the bug is crushed!

The test of the exploration style only uses code that contains obvious problems. However, the regression style test can guarantee frequent repair of a problem.

Fixing each bug not only makes your code healthier, but also gives you more time to think about your unit test.

 

 

3. What should I do next?

Testing is a huge task in our development career. In this chapter, we have mastered the foundation of unit testing. Below are some useful concepts:

  • Which asserted is used? Where can I use assertions?
  • Add a test to an existing app
  • Use the test in the program description
  • Explore and fix bugs
  • Make sure that fixed bugs do not appear again

 

The XCTest integrated in Xcode makes it very easy to establish a test suite. The test scope of the entire iOS field is very broad. More test concepts:

  • Mock objects
    • Simulate a realistic object in the test.
      • Http://ocmock.org/
  • UI testing
    • It can simulate user input, such as touch or text input.
  • Continuous integration (CI) systems
    • The unit test will be run automatically.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.