Reference no: EM132865245
ITAP2008 Software Testing - Victorian Institute of Technology
Lab 5
Creating a project and supporting unit tests
During this lab session, you'll go through the process of creating a new project, as well as some supporting unit tests.
Task 1: Creating a new library
In this task, you'll create a basic calculator library.
1 Open Visual Studio 2013.
2 From the main menu, select File | New | Project.
3 In the New Project dialog, select the Visual C# | Windows Desktop category and the Class Library template (As shown in Figure 1). Type "MyCalculator" as the Name and click OK.
4 In Solution Explorer, Right-click the Class1.cs and select Rename. Change the name to "Calculator.cs".
5 When asked to update the name of the class itself, click Yes.
6 Add the following Add method to Calculator.cs.
C#?
public int Add(int first, int second) { return first + second;
}
Note: For the purposes of this lab, all operations will be performed using the int value type. In the real world, calculators would be expected to scale to a much greater level of precision. However, the requirements have been relaxed here in order to focus on the unit testing.
Task 2: Creating a unit test project
In this task, you'll create a new unit test project for your calculator library. Unit tests are kept in their own class libraries, so you'll need to add one to the solution.
1. Right-click the solution node and select Add | New Project.
2. Select the Visual C# | Test category and the Unit Test Project template. Type "MyCalculator.Tests" as the Name and click OK. It's a common practice to name the unit test assembly by adding a ".Tests" namespace to the name of the assembly it targets.
The wizard will end by opening the default unit test file. There are three key aspects of this class to notice. First, it includes a reference to Visual Studio's unit testing framework. This namespace includes key attributes and classes, such as the Assert class that performs value testing. Second, the class itself is attributed with TestClass, which is required by the framework to detect classes containing tests after build. Finally, the test method is attributed with TestMethod to indicate that it should be run as a test. Any method that is not attributed with this will be ignored by the framework, so it's important to pay attention to which methods do and don't have this attribute.
3. The first thing you'll need to do with the unit test project is to add a reference to the project you'll be testing. In Solution Explorer, right-click the References node of MyCalculator.Tests and select Add Reference.
4. Select the Projects category in the left pane and check MyCalculator in the main pane. Click OK to add the reference.
5. To make the project easier to manage, you should rename the default unit test file. In Solution Explorer, right-click UnitTest1.cs and rename it to "CalculatorTests.cs".
6. When asked to rename the class itself, click Yes.
7. At the top of CalculatorTests.cs, add the following using directive.
C#
using MyCalculator;
8. Rename TestMethod1 to AddSimple. As a project grows, you'll often find yourself reviewing a long list of tests, so it's a good practice to give the tests descriptive names. It's also helpful to prefix the names of similar tests with the same string so that tests like AddSimple, AddWithException, AddNegative, etc, all show up together in various views.
C#
public void AddSimple()
Now you're ready to write the body of your first unit test. The most common pattern for writing unit tests is called AAA. This stands for Arrange, Act, & Assert. First, initialize the environment. Second, perform the target action. Third, assert that the action resulted the way you intended.
9. Add the following code to the body of the AddSimple method.
C#
Calculator calculator = new Calculator(); int sum = calculator.Add(1, 2); Assert.AreEqual(0, sum);
This test has only three lines, and each line maps to one of the AAA steps. First, the Calculator is created. Second, the Add method is called. Third, the sum is compared with the expected result. Note that you're designing it to fail at first because the value of 0 is not what the correct result should be. However, it's a common practice to fail a test first to ensure that the test is valid, and then update it to the expected behavior for success. This helps avoid false positives.
10. From the main menu, select Test | Windows | Test Explorer. This will bring up the Test Explorer, which acts as a hub for test activity. Note that it will be empty at first because the most recent build does not contain any unit tests.
12. The unit test should now appear in Test Explorer. Right-click it and select Run Selected Tests.
Note that while the test process is running, the progress bar in Test Explorer shows an indeterminate green indicator.
13. However, once the test fails, the bar turns red. This provides a quick and easy way to see the status of your tests. You can also see the status of each individual test based on the icon to its left. Click the test result to see the details about why it failed. If you click the CalculatorTests.AddSimple link at the bottom, it will bring you to the method.
C#
Assert.AreEqual(3, sum);
15. In Test Explorer, click Run | Run Failed Tests. Note that this option only runs the tests that failed in the last pass, which can save time. However, it doesn't run passed tests that may have been impacted by more recent code changes, so be careful when selecting which tests to run.
16. Now that the test passes, the progress bar should provide a solid green. Also, the icon next to the test will turn green. If you click the test, it will provide the basic stats for the test's run.
Task 3: Creating a new feature using test-driven development
In this task, you'll create a new feature in the calculator library using the philosophy known as "test- driven development" (TDD). Simply put, this approach encourages that the tests be written before new code is developed, such that the initial tests fail and the new code is not complete until all the tests pass. Some developers find this paradigm to produce great results, while others prefer to write tests during or after a new feature is implemented. It's really up to you and your organization because Visual Studio provides the flexibility for any of these approach.
1. Add the following method to CalculatorTests.cs. It is a simple test that exercises the Divide method of the library.
C#
[TestMethod]
public void DivideSimple()
{
Calculator calculator = new Calculator(); int quotient = calculator.Divide(10, 5); Assert.AreEqual(2, quotient);
}
2. However, since the Divide method has not yet been built, the test cannot be run. However, you can feel confident that this is how it's supposed to work, so now you can focus on implementation.
Strictly speaking, the next step should be to implement only the method shell with no functionality. This will allow you to build and run the test, which will fail. However, you can skip ahead here by adding the complete method since it's only one line.
3. Add the Divide method to Calculator.cs.
C#?
public int Divide(int dividend, int divisor) { return dividend / divisor;
}
4. From the main menu, select Build | Build Solution.
5. In Test Explorer, right-click the new DivideSimple method and select Run Selected Tests.
However, there is one edge case to be aware of, which is the case where the library is asked to divide by zero. Ordinarily you would want to test the inputs to the method and throw exceptions as needed, but since the underlying framework will throw the appropriate DivideByZeroException, you can take this easy shortcut.
6. Add the following method to CalculatorTests.cs. It attempts to divide 10 by 0.
C#
[TestMethod]
public void DivideByZero()
{
Calculator calculator = new Calculator(); calculator.Divide(10, 0);
}
7. Right-click within the body of the test method and select Run Tests. This is a convenient way to run just this test.
8. The test will run and fail, but that's expected. If you select the failed test in Test Explorer, you'll see that the DivideByZeroException was thrown, which is by design.
However, this is expected behavior, so you can attribute the test method with the ExpectedException attribute.
9. Add the following attribute above the definition of DivideByZero. Note that it takes the type of exception it's expecting to be thrown during the course of the test. C#
[ExpectedException(typeof(DivideByZeroException))]
10. In Test Explorer, right-click the failed test and select Run Selected Tests.
Task 4: Organizing unit tests
In this task, you'll organize the unit tests created so far using different groupings, as well as create custom traits for finer control over organization.
By default, Test Explorer organizes tests into three categories: Passed Tests, Failed Tests, and Not Run Tests. This is useful for most scenarios, especially since developers often only care about the tests that are currently failing.
1. However, sometimes it can be useful to group tests by other attributes. Right-click near the tests and select Group By | Project.
This will organize the tests based on the project they belong to. This can be very useful when navigating huge solutions with many test projects.
2. Another option is to organize tests by the class they're part of. Right-click near the tests and select Group By | Class.
The tests are now grouped by class, which is useful when the classes are cleanly divided across functional boundaries.
3. Yet another option is to organize tests by how long they take to run. Right-click near the tests and select Group By | Duration.
Grouping by duration makes it easy to focus on tests that may indicate poorly performing code.
4. Finally, there is another option to organize tests by their traits. Right-click near the tests and select Group By | Traits.
By default, a test method doesn't have any traits.
5. However, traits are easy to add using an attribute. Add the following code above the AddSimple method. It indicates that this test has the Add trait. Note that you may add multiple traits per test, which is useful if you want to tag a test with its functional purpose, development team, performance relevance, etc.
C#
[TestCategory("Add")]
6. Add TestCategory attributes to each of the divide tests, but use the category Divide.
7. From the main menu, select Build | Build Solution.
8. Another useful attribute for organizing tests is the Ignore attribute. This simply tells the test engine to skip this test when running. Add the following code above the AddSimple method.
C#
[Ignore]
9. In Test Explorer, click Run All to build and run all tests.
10. Note that AddSimple has a yellow exclamation icon now, which indicates that it did not run as part of the last test pass.
There are a few more test attributes that aid in the organization and tracking of unit tests.
- Description allows you to specify a description for the test.
- Owner specifies the owner of the test.
- HostType allows you to specify the type of host the test can run on.
- Priority specifies the priority at which this test should run.
- Timeout specifies how long the test may run until it times out.
- WorkItem allows you to specify the work item IDs the test is associated with.
- CssProjectStructure represents the node in the team project hierarchy to which this test corresponds.
- CssIteration represents the project iteration to which this test corresponds.
Lab 6
Review Questions
1. Explain the purpose of each of the following. What types of error is each likely to find?
a. Stress testing
b. Facility testing
c. Volume testing
d. Storage testing
e. Recovery testing
f. Security
g. Performance
h. Storage
i. Documentation
j. Procedure
2. What is usability testing?
3. If L =10 and n=2 calculate E using Jakob neilson equation. Identify number of users need in the usability testing (Refer the graph in the lecture slides).
Practice Questions
1. Evaluate following websites based on criteria given below.
a. Bunnings Warehouse
b. Victorian Institute of Technology
c. Melbourne University website
d. Woolworth Super markets
2. Design a questionnaire to assess the usability of a search bar on a website. Refer lecture notes for examples.
Lab 7
Creating a project and supporting unit tests
During this lab session, you'll go through the process of creating a new project, as well as some
supporting unit tests.
Task 1: Creating a new class
In this task, you'll create a basic class Calculator.cs.
1 Open Visual Studio 2013.
2 From the main menu, select File | New | Project.
3 In the New Project dialog, select the Visual C# | Windows Desktop and Console Application template (As shown in Figure 1). Type "Calculator" as the Name (This will be the namespace) and click OK.
4 In Solution Explorer, Right-click the Program.cs and select Rename. Change the name to "MyCalculator.cs".
5 When asked to update the name of the class itself, click Yes.
6 Add the following C# code for the class MyCalculator.cs.
C#?
static void Main(string[] args)
{
int a = 5, b = 8, c = 233; int d = a + c - b; Console.WriteLine(d);
}
Note: For the purposes of this lab, all operations will be performed using the int value type. In the real world, calculators would be expected to scale to a much greater level of precision. However, the requirements have been relaxed here to focus on the debugging.
Task 2: Adding a Breakpoint
In this task, you'll add a breakpoint to the class and the code will stop execution from that breakpoint. Then you can manually run the code using key F11
There are different ways you can add break points.
1. First move the cursor to the line you need to add breakpoint. And from the menu select add Breakpoint.
2. Place a breakpoint by clicking in the left gutter
Once you added the breakpoint your IDE should now look something as in the figure 3.
Task 3: Building and Debugging Application
1. Build application, by clicking the Build |Build Solution
2. Now select Debug | Start Debugging.
3. Now select Debug | Start Debugging.
4. The program will stop at the breakpoint. Now use F11 to go forward in the code (line by line). You will be able to traverse line by line in the program. At the same time, you can check the attribute values and check the problems with assignment of the values.
Task 4: Understanding Debug Menu
Figure 12 shows the Debug menu with Visual Studio 2013. Using this user can start debugging process
by adding breakpoints. And stop debugging. Can step into codes and go through one line by line to examine the code.
Task 5: Debugging a Small Code
1. Create a new C# class with the name CalcFactorial. New Project | Windows Desktop | Console
Application
2. Add following code between class brackets. C#
static void Main(string[] args)
{
Console.WriteLine("Enter a Number to find Factorial"); int number = Convert.ToInt32(Console.ReadLine());
int fact = getFactorial(number);
Console.WriteLine("{0} Factorial is {1}", number, fact);
}
// New method getFactorial
public static int getFactorial(int num) { if (num == 1)
{
return 1;
}
return num * getFactorial(num-1);
}
3. Add breakpoint to the code on the keyboard input assignment statement. (Use enters the number here and assign the value on the integer type number variable.)
4. Build and debug the console application. Debug | Start Debugging
5. The application starts for the input.
6. User enters the value. (Note: You can enter any integer value.)
7. Now press F11. And move forward in the code. Note the yellow arrow. The yellow arrow shows that how F11 moves through you the code. It has moved to the next line and highlighted in
yellow. Same time note that the Autos section in the left hand side bottom input 5 has assigned on the variable number (this shows in red color).
8. Press F11. Observe how the yellow arrow moves.
9. The pointer checks the if condition.
10. Move the cursor onto the if statement. Then it shows whether the values assigned satisfy the condition or not. (Note: in the following example the statement become false due to not meeting the condition.)
11. Next F11 press.
12. The function getFactorial() is a recursive function and called recursively. Next f11 press will call the function again.
13. Now notice that the value for num variable is 4. Still does not meet the condition criteria.
14. The third call for function getFactorial(). The function will be recursively called and you will be able to see how the pointer moves and how conditions will be met.
15. Meeting if condition. The recursive call will deduct num variable and now numis 1 and enters to the if condition. See the display. It says now the condition is true with num variable.
16. Returning 1. Going into if condition and returning 1.
17. For the next F11 the pointer will exit from the function getFactorial and returns to the main method. Then executes Console.WriteLine statement and prints output on the console.
18. Printing the output on the console.
Task 5: Practice - How loops works - Understand by debugging
1. Create new console application and add following code segment to that.
C#
class Stars
{
static void Main(string[] args)
{
for (int i = 0; i <= 3; i++ )
{
for (int j = 0; j <= 3; j++)
{
Console.Write("*");
}
//Console.WriteLine();
}
Console.ReadLine();
}
2. Add breakpoint to the outer for loop as showing in the Figure 30.
3. Run the debugging process and see how for loops works and prints the stars.
Task 4: Exercises
1. Use following C# code segment.
o Expected output = 288
o Actual output = 219
2. Debug the code to locate the error and fix the error.
C#
class Stars
{
static void Main(string[] args)
{
int a = 48; int b = 2; int c = 9; int d = 3;
int f = a/b*9+3;
Console.WriteLine("The answer is {0}",f);
Console.ReadLine();
}
}
Lab 8
Review Questions.
1. In an agile environment who is responsible for quality of the software?
2. In an Agile team, who is responsible for quality?
3. What is a spint in agile environment?
4. What is a backlog?
5. When the customer in an Agile project provides feedback indicating that a piece of functionality was not implemented correctly, what should the Agile team do with this information?
Practice Questions
1. You have been given following story :
"As a plant lover who travels frequently, I want to have an automated watering system,
so that my
plants won't die."
You have also been given the following acceptance criteria:
a. The water should turn on when the temperature is > 85 degrees and the moisture content of the soil changes from "normal" to "dry".
b. The water should be dispersed for 5 minutes at the rate of 0.5 ounces per minute.
Which one of the following provides the proper values to use to achieve 100% two- value boundary value analysis coverage with the minimum number of test cases?
2. You are testing a story for a mobile banking application and you have noticed that the response time seems slow. You have checked the acceptance criteria for the story and nothing is mentioned regarding performance requirements. What should you do now?
3. You have identified a usability risk with the mobile application you are currently testing. When the application loses connectivity with the web server, the user is not informed of the problem and all information entered after that point is lost. What is a reasonable assessment of this risk (High, Medium or Low)?
You are a tester in a Scrum team. You have been testing the product for several iterations and you are noticing that the error message format and text are inconsistent. For example, when the user enters an invalid address in one part of the application, they are given the message "Invalid input" in a red font whereas when they enter an invalid phone number they are given the message "The phone number you have entered is not in a valid format. Please enter the phone number as (xxx) xxx-xxxx" in a blue font.
Note: All figures are attached in below file.
Attachment:- Lab Tutorials.rar