Original: NUnit V2.1
Original: QuickStart.doc of NUnit Documents
Translation: lover_p
-------------------------------------------------- ------------------------------
[Translator]
Throughout the development of software, testing has become an important part of software development, usually testing in a software development cycle to take half time or more. In the test, the unit test is more than the first step in the long march, and the unit test is perfect, directly affects the efficiency of the later integrated test. Many software can be completed automatically, NUNIT is one of them. This is a unit test software that is named JUnit, which belongs to the XUnit family (in
Http://www.nunit.org We can get this software for free).
[text]
Let us start from a simple example. Suppose we are writing a bank app, and we have a basic class of this field - Acount. Account supports deposit, withdrawal, and fund transfer. This Account class looks like this:
Namespace bank {
Public class account {
PRIVATE FLOAT Balance;
Public void deposit (float amount) {
BALANCE = Amount;
}
Public void withdraw (float amount) {
BALANCE - = Amount;
}
Public void Transferfunds (Account Destination, Float Amount) {
}
Public float balance {
Get {
Return balance;
}
}
}
}
Now let's write a test - AcountTest for this class. The first class method we want to test is TransferFunds.
Namespace bank {
Using nunit.framework;
[TestFixTure]
PUBLIC CLASS Accenttest {
[TEST]
Public void transferts () {
Account Source = new account ();
Source.Deposit (200.00F);
Account destination = new account ();
Destination.Deposit (150.00F);
Source.Transferfunds (Destination, 100.00F);
AskERT.Arequal (250.00F, Destination.balance);
AskERT.Arequal (100.00F, Source.balance);
}
}
}
First of all, this class is related to an [TestFixTure] feature (attribute) - which means that this class contains test code (this feature can be inherited). This class must be public, but his parent class is not limited. This class must also have a default constructor.
One of the only ways in the class - TRANSFERFUNDS (), is associated with a [TEST] feature - which means it is a test method. The return value of the test method must be VOID and cannot have parameters. In our test method, we have initialized the object being tested, perform the method of test and check the status of the object. The Assert class defines a set of methods to check the given conditions. In our example, we use the areequal () method to ensure that the two accounts have the correct balance after the transaction (this method has a lot of overload, we are here The version used in the example has two parameters: the first parameter is our expected value, the second parameter is the actual value). Compile and run this example. Suppose you have compiled your test code to Bank.dll. Open the Nuint GUI (the installer creates a shortcut in your desktop and "Programs" menu), open the GUI, select the file-> Open menu item, find your bank.dll and select in the "Open" dialog box it. After Bank.dll is loaded, you will see a test tree structure in the panel on the left, and a set of state panels on the right. Click the Run button, the status and test tree species TransferFunds nodes become red - our test failed. The "ERRORS AND FAILES" panel displays the following message - "Transferfunds: Expected <250> But Was <150>", in its piles tracking panel reports the location of the test failed in the code - "At Bank. AccountTest.Transferfunds () in C: /NUnit/banksampletests/accounttest.cs: line 17
This is the expected result because we have not implemented TransferFunds () methods. Now let's get it. Don't close the GUI, return to your IDE and modify the code, so that your transferts () method looks like this:
Public void Transferfunds (Account Destination, Float Amount) {
Destination.Deposit (Amount);
WITHDRAW (AMOUNT);
}
Now recompile your code and click the RUN button in the GUI - the status bar and the number node have turned green. (Note that the GUI will automatically reload the assembly for you; we can continue to work in the IDE and write more tests.
Let's add some error detection for our Account code. Add a minimum balance limit for your account, maintain its continuous operation through your minimum overdraft protection fee. First we add a minimum balance protection property for the Account class:
Private float minimumbalance = 10.00F;
Public float minimumbalance {
Get {
Return minimumbalance;
}
}
We use an exception to point out overdrafts:
Namespace bank {
Using system;
Public class insufficientfundSexception: ApplicationException {
}
}
Add a new way to our AccountTest class:
[TEST]
[EXPECTEDEXCEPTION (TypeOf (Insuff (InsufficIntfundSexception)]]]
Public void TransferwithinSUFFICIENTFUNDS () {
Account Source = new account ();
Source.Deposit (200.00F);
Account destination = new account ();
Destination.Deposit (150.00F); Source.Transferfunds (Destination, 300.00F);
}
This test method is associated with the [testedException] feature other than [TEST] - this pointing that the test code wants to throw an exception to the specified type; if there is no such anomaly in the execution process - the test will Will fail. Compile your code and return to the GUI. Since you compile your test code, the GUI will gray gray and refactor the test tree, it seems that this test has not yet been runned (GUI can monitor the change of the test assembly, and update when the test tree structure changes - For example, add a new test). Click the "Run" button - we got another red status bar again. We got the following failure message: "TransferWithinsufficeTfunds: InsufficientFundSexception Was Expected". Let's change the code of Account again, and modify the transferts () method like this:
Public void Transferfunds (Account Destination, Float Amount) {
Destination.Deposit (Amount);
Balance - Amount Throw new insufficientfundSexception (); WITHDRAW (AMOUNT); } Compile and run test - green. success! However, wait, look at the code we just wrote, we will find that the bank will lose money during each unsuccessful transfer. Let us write a test to confirm our guess. Add this test method: [TEST] Public void TransferwithinSufficientFundsatomicity () { Account Source = new account (); Source.Deposit (200.00F); Account destination = new account (); Destination.Deposit (150.00F); Try { Source.Transferfunds (Destination, 300.00F); } Catch (insufficientfundsexception ") { } AskERT.Arequal (200.00F, Source.balance); AskERT.Areequal (150.00F, Destination.balance); } We tested the transaction properties of the method - all the operations were successful. Compile and run - red. Yes, we lose 300 yuan in the order of 300 yuan. The Source account has the correct balance of 150.00, but the Destination account shows: $ 450.00. How should we modify it? We can only put the minimum balance inspection to the data update before: Public void Transferfunds (Account Destination, Float Amount) { IF (Balance - Amount Throw new insufficientfundSexception (); } Destination.Deposit (Amount); WITHDRAW (AMOUNT); } If the WITHDRAW () method throws another exception? Should we execute a remediation process in the CATCH block or rely on our trading manager to reload the status of the object? At some point we must answer such a problem, but not now; how can we deal with this failure test - delete it? A nice way is to temporarily ignore it to add the following features in your test method: [TEST] [Ignore ("Need to Decide How To Implement Transaction Management In the Application")]]]]] Public void TransferwithinSufficientFundsatomicity () { // code is the same } Compile and run - Yellow bar. Click the Test Not Run tab, you will see Bank.accountTest.TransferWithinsufficientFundsatomicity () listed together in the list along with the reason why this test is ignored. Look at our test code, we can see some suitable reconstruction. All methods share a group of public test objects. Let us put these initialization code in a setup method and reuse them in all tests. The reconstruction of our test class is like this: Namespace bank { Using system; Using nunit.framework; [TestFixTure] PUBLIC CLASS Accenttest { Account Source; Account destination; [Setup] Public void init () { Source = new account (); Source.Deposit (200.00F); Destination = new account (); Destination.Deposit (150.00F); } [TEST] Public void transferts () { Source.Transferfunds (Destination, 100.00F); AskERT.Arequal (250.00F, Destination.balance); AskERT.Arequal (100.00F, Source.balance); } [TEST] [EXPECTEDEXCEPTION (TypeOf (Insuff (InsufficIntfundSexception)]]] Public void TransferwithinSUFFICIENTFUNDS () { Source.Transferfunds (Destination, 300.00F); } [TEST, Ignore "Need to Decide How To Implement Transaction Management In The Application" )]] Public void TransferwithinSufficientFundsatomicity () { Try { Source.Transferfunds (Destination, 300.00F); } Catch (insufficientfundsexception ") { } AskERT.Arequal (200.00F, Source.balance); AskERT.Areequal (150.00F, Destination.balance); } } } Note that this initialization method has a common initialization code, its return value type is Void, no parameters, and is marked by the [Setup] feature. Compile and run - the same yellow strip! ============ full text ========== If you have NUNIT V2.1, you can start-> program -> NUnit v2.1-> quickstart Original (English version).