Software testing is one of the most important phases of the Software Development Life Cycle (SDLC). The delivery of the end product is based on better design, better coding, better testing, and meeting the requirements. The quality of the product is measured by testing the product based on functional and non-functional requirements with the help of testing tools and techniques. The tools are useful in simulating a real life situation and the user load. For example, testing a web application with more than 1000 user load is a very time consuming and tedious task if we do it manually. But the performance testing tool that comes along with Visual Studio 2010 can simulate this scenario and test it in a very short period of time. Visual Studio 2010 provides additional tools for testing all type of applications and scenarios such as Unit testing, Load Testing, Web testing, Ordered testing, and generic testing.
This chapter provides a high level overview on all the testing tools and techniques supported by Visual Studio 2010. This chapter covers the following topics:
Testing as part of the software development life cycle
Types of Testing
Test Management in Visual Studio 2010
Testing Tools in Visual Studio 2010
Before getting into the details of the actual testing using Visual Studio 2010 let us find out the different tools provided by Visual Studio 2010 and their usage and then we can execute the actual tests. Visual Studio 2010 provides different tools for testing and management such as the Test List Editor and the Test View. The test projects and the actual test files are maintained in Team Foundation Server (TFS) for managing the version control of the source and the history of changes. Using Test List Editor we can group similar tests, create any number of Test Lists, and add or delete tests from a Test List.
The other aspect of this chapter is to see the different file types generated in Visual Studio during testing. Most of these files are in XML format, which are created automatically whenever a new test is created.
For the new learners of Visual Studio, there is a brief overview on each one of those windows as we are going to deal with these windows throughout all or most of the chapters in this book. While we go through the windows and their purposes, we can check the Integrated Development Environment (IDE) and the tools integration into Visual Studio 2010.
The main objective of testing is to find the defects early in the SDLC. If the defect is found early, then the cost will be lower than when the defect is found during the production or implementation stage. Moreover, testing is carried out to assure the quality and reliability of the software. In order to find the defect as soon as possible, the testing activities should start early, that is in the Requirement phase of SDLC and continue till the end of the SDLC.
In the Coding phase various testing activities take place. Based on the design, the developers start coding the modules. Static and dynamic testing is carried out by the developers. Code reviews and code walkthroughs are conducted by the team.
Unit Testing: This is the first stage of testing in the SDLC. This is performed by the developer to check whether the developed code meets the stated functionality. If there are any defects found during this testing then the defect is logged against the code and the developer fixes it.
The code is retested and then moved to the testers after confirming the code without any defects for the purpose of functionality. This phase may identify a lot of code defects which reduces the cost and time involved in testing the application by testers, fixing the code, and retesting the fixed code.
Integration Testing: This type of testing is carried out between two or more modules or functions together with the intention of finding interface defects between them. This testing is completed as a part of unit or functional testing and, sometimes, becomes its own standalone test phase. On a larger scale, integration testing can involve putting together groups of modules and functions with the goal of completing and verifying that the system meets the system requirements. Defects found are logged and later fixed by the developers. There are different ways of integration testing such as top-down and bottom-up.
The Bottom-Up approach is exactly opposite to the top-down approach. In this case the low level functionalities are tested and integrated first and then the high level functionalities are tested. The disadvantage of this approach is that the high level or the most complex functionalities are tested later.
The Umbrella approach uses both the top-down and bottom-up patterns. The inputs for functions are integrated in the bottom-up approach and then the outputs for functions are integrated in the top-down approach.
System Testing: This type of testing compares the system specifications against the actual system. The system test design is derived from the system design documents and is used in this phase. Sometimes system testing is automated using testing tools. Once all the modules are integrated, several errors may arise. Testing done at this stage is called system testing. Defects found in this type of testing are logged by the testers and fixed by the developers.
Regression Testing: This type of testing is carried out in all the phases of the testing life cycle, once the defects logged by the testers are fixed by the developers or if any new functionality changes due to the defects logged. The main objective of this type of testing is testing with the intention of determining if bug fixes have been successful and have not created any new defects. Also, this type of testing is done to ensure that no degradation of baseline functionality has occurred and to check if any new functionality that was introduced in the software caused prior bugs to resurface.
Visual Studio provides a range of testing types and tools for testing software applications. The following are some of those types:
Web Performance Test
Coded UI Test
In addition to these types there are additional tools provided to manage, order the listing, and execution of tests created in Visual Studio. Some of these are the Test View, Test List Editor, and Test Results window. We will look at the details of these testing tools and the supporting tools for managing testing in Visual Studio 2010.
Unit testing is one of the earliest phases of testing the application. In this phase the developers have to make sure the code is producing the expected result as per the stated functionality. It is extremely important to run unit tests to catch defects in the early stage of the software development cycle. The main goal of unit testing is to isolate each piece of the code or individual functionality and test if the method is returning the expected result for different sets of parameter values.
A unit test is a functional class method test which calls a method with the appropriate parameters, exercises it, and compares the results with the expected outcome to ensure the correctness of the implemented code. Visual Studio 2010 has great support for unit testing through the integrated automated unit test framework, which enables the team to write and run unit tests.
Visual Studio has the functionality to automatically generate unit test classes and methods during the implementation of the class. Visual Studio generates the test methods or the base code for the test methods but it remains the responsibility of the developer or the team to modify the generated test methods and to include the code for actual testing. The generated unit testing code will contain several attributes to identify the Test Class, Test Method, and Test Project. These attributes are assigned when the unit test code is generated from the original source code. Here is a sample of the generated unit test code.
A Unit test is used by developers to identify functionality change and code defects. We can run the unit test any number of times and make sure the code delivers the expected functionality and is not affected by new code change or defect fix.
All the methods and classes generated for the automated unit testing are inherited from the namespace
Manual testing is the oldest and the simplest type of testing but yet very crucial for software testing. The tester would be writing the test cases based on the functional and non-functional requirements and then testing the application based on each test case written. It helps us to validate whether the application meets various standards defined for effective and efficient accessibility and usage.
Manual testing comes to play in the following scenarios:
There is not enough budget for automation
The tests are more complicated or too difficult to convert into automated tests
Not enough time to automate the tests
Automated tests would be time consuming to create and run
The tested code hasn't stabilized sufficiently for cost effective automation.
We can create manual tests by using Visual Studio 2010 very easily. The most important step in a Manual test is to document all the required test steps for the scenario with supporting information, which could be in a separate file. Once all the test cases are created, we should add the test cases to the Test Plan to be able to run the test and gather the test result every time we run the test. The new Microsoft Test Manager tool helps us when adding or editing the test cases to the Test Plan. The following are additional Manual testing features that are supported by Visual Studio 2010:
Running the Manual test multiple times with different data by adding parameters
Create multiple test cases using an existing test case to get the base test case first and then customize or modify the test
Sharing test steps between multiple test cases
Remove test cases from the test if not required
Adding or copying test steps from Microsoft Excel or Microsoft Word or any other supported tool
There are a lot of other manual testing features that are supported in Visual Studio 2010. We will see those features explained in Chapter 2, Test Plan, Test Suite, and Manual Testing.
Web Performance Tests are used for testing the functionality and performance of the web page, web application, web site, web services, and combination of all of these. Web Performance Tests can be created by recording the HTTP requests and events during user interaction with the web application. The recording also captures the web page redirects, validations, view state information, authentication, and all the other activities. All these are possible by manually building the web tests using the Web Performance Test editor but this takes more time and is more complex. Visual Studio 2010 provides the automated Web test feature which takes care of capturing all HTTP request and response events while recording the user interaction and generating the test.
There are different validation rules and extraction rules used in Web Performance Testing. Validation rules are used for validating the form field names, texts, and tags in the requested web page. We can validate the results or values against the expected result as per the business needs. These validation rules are also used for checking the processing time taken for the HTTP request.
Extraction rules in Web Performance Tests are used for collecting the data from the web pages during requests and responses. Collecting this data helps us in testing the functionality and expected result from the response.
Providing enough data for the test methods is very important for the success of automated testing. Similarly, for Web Performance Tests we need to have a data source from which the data would be populated to the test methods and the web pages would be tested. The data source could be a database, a spreadsheet, or an XML data source. There is a data binding mechanism in Web Performance Tests which takes care of fetching the data from the source and provides the data to the test methods. For example, a reporting page in a web application definitely needs more data to test it successfully. This is also called the data driven web test.
Simple Web Performance Tests generate and execute the test as per the recording with a series of valid flows of events. Once the test is started there won't be any intervention and it is not conditional.
Coded Web Performance Tests are more complex but provide a lot of flexibility. These types of tests are used for conditional execution based on values. Coded web tests can be created manually or generated from the Web Performance Test recording. We can choose the language for generating the code for the Web Performance Test such as C# or VB.NET. Using the generated code, we can control the flow of test events by customizing the code. A coded Web Performance Test is a powerful and highly customizable test for web requests.
The previous versions of Visual Studio provided all facilities to test application functionality and performance but there is no test type to test the UI part of the application, whether it is Web or Windows. Visual Studio 2010 has a very good new feature for the UI test to access the controls in a web page and verify the values.
The Coded UI test Test can be generated from action recordings coming from MTM or can be recorded and generated directly in Visual Studio. A Coded UI test generates a UIMap object that represents the controls, windows, and assertions. Using these objects and methods we can perform actions to automate the test. The coded UI test also creates other supporting files such as:
CodedUITest.cs: A File which contains the test class, test methods, and assertions
UIMap.uitest: The XML model for the UIMap class which contains the windows, controls, properties, methods, and assertions
UIMap.Designer.cs: Contains the code for the
UIMap.cs: All customization code for the UI Map would go into this file
Load Testing is a method of testing used to identify the performance of critical situations and the maximum workload the application can handle. In the case of a desktop or a standalone application the user load is predictable and it is easy to tune the performance, but in the case of a multi-user application or a web application it is necessary to determine the application behavior under normal and peak load conditions.
Visual Studio 2010 provides a Load Test wizard which helps in creating the Load Test for different scenarios. These are the parameters set using the Load Test wizard:
Load Test pattern defines how the user will run the app at any point
Test mixes define which tests will be used for testing
Browser Mix and Network Mix define the possible browser and the network configuration related to the actual
Counter Sets define which performance counters are collected from the load test agents and the system
Run settings define the test run such as how long the test should be run
So before we release this web site to the customers or the end users, we should check the performance of the application so that it can support the mass end user group. This is where Load Testing is very useful to test the application along with the Web test or Unit test.
The Load Test is always driven by the collection of Web and Unit tests. The Web Performance Test is added to a Load Test to simulate multiple users opening simultaneous connections to the same web application and making multiple HTTP requests. The Load Test starts with a minimum number of virtual users and then gradually increases the user count to check the performance at the peak user load.
The Load Test can be used to test the performance of the service components to find out the servicing capacity of the component for the client requests. One good example would be to test the data access service component that calls stored procedure in the backend database and returns the results to the client application. Unit tests would be used as part of a Load Test in these cases.
With VS 2010 we have the option of capturing individual tests and saving the entire test result of individual test runs within the Load Test such as a failed Web Performance Test or a failed unit test. This is very helpful when debugging the Load Tests. Results of different tests can be saved in a repository to compare the set of results and improve performance.
VS also provides the Load Test Analyzer, which provides the summary and details of test runs from the Load Test result.
We will see more about setting the Load Test properties, working with tests, and analyzing the Load Test results later in this book in Chapter 7, Load Testing.
There are situations where the execution of a test is dependent on another test. In order to execute the dependent test successfully, the parent test should be executed first. Ordered tests merely consist of setting the order for all the tests in an ordered Test List. Sometimes there would be a test B, which depends on the result produced by test A in the list of tests executed. If we don't set the order that test A should be run before running test B then the entire test would fail.VS 2010 provides the feature to set the execution or running order for the tests through the Test View window. We can list all available tests in the Test View and choose the tests in an order using different options provided by Visual Studio and then run the tests. Visual studio will take care of running the tests in the order we have chosen in the list.
Once we are able to run the tests successfully in an order, we also expect the same ordering in getting the results. Visual Studio provides the results of all the tests in a single row in the Test Results window. Actually, this single row result will contain the results of all the tests run in the order. We can just double-click the single row result to get the details of each of the tests run in the ordered test.
An ordered test is the best way to control tests and run tests in an order.
We have seen different types and ways of testing applications but there are situations where we might end up having other third party applications for testing, which were not developed using Visual Studio. We might have only the executable or binaries for the application and may not have the supported testing tool for those applications. This is where we need the generic testing method, which is just a way of testing third party applications using Visual Studio.
Generic tests are used to wrap existing tests. Once the wrapping is done then it is just another test in VS.
Using Visual Studio we can collect the test results and gather the code coverage data too. We can manage and run the generic tests in Visual Studio just like others tests. In fact, the test result output can be published to the Team Foundation server to link it with the code build used for testing.
Visual Studio 2010 has great testing features and management tools for testing. These features are greatly improved from previous versions of VS. The Test Impact View is the new test management tool added to the existing tools such as Test View, Test List Editor, Test Results, Code coverage Results, and Test Runs from the main IDE.
Team Explorer is the application tier that is integrated into Visual Studio to connect the source control tool, Team Foundation Server. Using this explorer, the developer can browse through the Team Projects in the TFS. TFS is the central source control repository for managing and controlling Team Projects. From Team Explorer IDE, we can connect to the Team Foundation Server, and the Team Project collection, and Team Project. After connecting to the server, we can use Team Explorer to browse through the details of the Team Project.
Team Explorer provides features to work with Team Project details such as:
Accessing project process guidance documents that explain the process to be followed for the Team Project such as work items, reports, queries, and work products.
Managing work items such as tasks, defects, issues, and requirements.
Importing and exporting work items.
Accessing the project files and source code.
Adding, removing, configuring, and managing Team Projects.
Creating, managing, and automating project builds.
Managing favorites which are the shortcuts to the favorite node of the Team Project.
Managing reports. It could be defect reporting or any type of work items reporting.
Visual Studio 2010 provides many tools to create, run, debug, and view results of tests. The following is an overview of the tools and windows provided by Visual Studio to view test details and test output details. We will look into more details of the actual usage of these tools later, in Chapter 9, Managing and Configuring a Test.
Let us see how we can create a new test project using Visual Studio 2010 and then we will test a sample project to get to know the tools and features.
Open Visual Studio 2010 and open the solution. We will not go into the details of the sample application AddNumbers now but we will just create a test project for the sample application and see the features of the tools and windows. The application referred to throughout this chapter is a very simple application for adding two numbers and showing the result.
In the same way as adding the projects and code files to the solution, we have to create the test project and test files, and add the test project to the solution. There are different ways of creating test projects under the solution:
Select the solution and add a project using the Add | New Project.... Then select the project type as Test from the list of project types under the language which we are going to use. Then select the template as Test Project.
Select the solution and then from the top toolbar menu option select the option Test | New Test.... This will list all the test type templates to offer the type of template we need for the testing. You can see the option which is a dropdown saying Add to Test Project with the options as list of
<projectnames>, Create a new Visual C# test projectâ¦, Create a new Visual Basic test project..., and three more options.
For our sample testing application, we will select the second option mentioned previously and choose the simple Unit Test type.
The Add New Test dialog contains nine different template options for creating tests. Unit testing templates consist of four types, one is a basic unit test, the second one is Database unit test, the third for the general unit test, and the fourth is for using Unit Test Wizard. The following are the file extensions for each of the VS test types shown in the preceding image:
.csis for all types of unit tests and coded UI tests
.generictestis for the Generic test type
.loadtestis for a test which is of type Load Test
.webtestis for Web Performance Testing
After selecting the test type, give a name for the test in the Test Name field. Select the Create new Visual C# test Projectâ¦ in the Add to Test Project option. Now assign a name for the new test project. Let us name it
Now we can see that there are two files created,
<ProjectName>.vsmdi, which is the metadata file, and the Local.testsettings file created under the solution items for the test projects. The metadata file is an XML file which contains all the information about the tests list. Let us add a couple more tests to this test project to run different tests using the tools available.
Visual Studio 2010 provides the Test View window to view the list of all tests available in the current solution. Test View provides the option to change the column display, grouping of tests based on test properties, search for specific tests from the list, and select and run the test from the list as well. The test view window is available under the Test | Windows menu option in Visual Studio IDE. The following screenshot shows a sample of the Test View window which displays the list of all tests created in the current solution:
The Test View window has its own toolbar for the multiple operations that can be performed on the list. The leftmost option in the toolbar is the run and debug option with which we can start and debug the selected tests in the list.
The second and third options in the toolbar are for Filtering the list by choosing the column from the dropdown and entering matching text in the keyword area. When you submit filter conditions using the button to the right, the list gets filtered and only the test matching the condition is shown. For example, the following screenshot shows the list of tests filtered with Test Type as Unit Test:
The third option in the toolbar is to group the lists based on some common property of the tests. Clear the above selected filters to list all available tests.
Now select any of the values available from the Group By dropdown.
On selecting a value from the dropdown we can see the list regrouped based on the type selected.
The following screenshot shows the tests grouped by Test Type. There are two unit tests, one Generic test, and one Ordered test.
The following screenshot shows the tests grouped by Class Name. The Ordered test and Generic test do not have class names as they are not derived from any class and do not have a class.
In Test View, we can customize the display of columns and the sorting of these columns:
Right-click on the columns that are available in the Test View window, and select the Add/Remove Columns option and the Add/Remove Columns dialog box gets displayed.
Check and uncheck the columns based on the columns that are needed on the display.
To change the sorting order of the list, just click on the column header. If the same column is already sorted then the sorting order will be changed.
All features available in Test View are also available in the Test List Editor with some additional features such as creating new Test Lists by selecting multiple tests from the available list of tests.
The following screenshot is the Test List Editor opened using the menu option, Test | Windows | Test List Editor. The editor shows all available tests under All Loaded Tests:
The toolbar in the Test List Editor window has the same features as we saw in the Test View window. But you can see the detail section of the list window is split into two panes. The left pane of the window has three nodes and the right pane displays all the tests in the lists based on the selection in the left pane. The Test List editor displays the following three options as nodes:
List of Tests displays the available Test Lists and acts as an interface to create a new Test List
Tests Not in a List is the second option, which provides all the tests which are not part of any of the Test Lists
All Loaded Tests is the third option, which provides the list of all the tests in the solution whether the test is part of any list or not
The following screenshot contains a Test List which contains a couple of tests selected from the available list of all tests in the solution. You can right-click on the node and select the Create New Test List option and provide the required details to create the new Test List.
After creating the Test List and adding the required tests to the corresponding list, you may want to check the tests that are not part of any of the list. The screenshot here shows the second option of displaying the tests not part of any of the list:
Now we know that there are tests which are part of a Test List and some are not part of any List but how can we see all of the available tests under the solution? To get this, you have to choose the third option, All Loaded Tests, from the Editor window.
This window provides the status of all test runs including the error messages and an option to rerun the test irrespective of whether it passed or failed. Using this window, we can export the test results or import the exported results. We can also get detailed information about the test run by double-clicking on the test result. Select the unit test and Coded UI test from Test View or Test List Editor and run the tests.
The following screenshot shows the different stages of test runs in the result window. From the following image we see that the first test is still in the process of test execution and the second test is pending execution.
The following image shows the final execution status of the selected tests. One test executed successfully and the other test failed. The error message for the failed test is also displayed. We can also select a test from the result window and rerun a test. This would be very useful in executing a failed test.
To get more information such as the detailed error message, the stack trace of the error, the time duration of the test run, and other details, just double-click on the test result which will open a new window with more details.
On execution of any test in VS, a test result file is created with all the test result information. The file is automatically created with the username and the machine name with date and the extension
.trx . In the preceding image the name for the test result file is generated as [email protected] 2010-05-25 23_24_32. The test result file is an XML file with all the result information. The following screenshot shows the default folder structure and the files created for the test results:
In the case of multiple test runs and multiple tests, we sometimes need the test to be stored somewhere or to keep the copy of the test run trace for future analysis of the test, or we may prefer sharing the result with another team member. In that case we can use Export Test Run Results or Export Selected Test Results from the toolbar which exports the entire trace file for the tests selected.
Visual Studio provides this code coverage feature to find out the percentage of code that is covered by the test execution. Through this window, we can find out the number of lines covered in each method by the test. To activate the code coverage for the test project, the test settings have to be changed. This is a little bit different from VS 2008. To configure the test project, open the local.testsettings file and select the Data and Diagnostics option from the list of settings options.
Choose Code Coverage from the list of diagnostics and enable it. You can see that the Configure option on top of the list is enabled now. Click on Configure to open the Code Coverage Detail page which would lists all the projects and artifacts available under the solution. Choose the required artifacts from the list for which the code coverage has to be captured during the test run. Apply the settings and close the window.
After completing the configuration, select the test from the Test View/List Editor and run the test. The test run will capture the code coverage and store the coverage result in a separate file with the default name of
Select the tests run result from the results window and then right-click and choose the code coverage results or open this using Test | Windows | Code Coverage Results from the menu option. The following screenshot shows the code coverage results from the test run. The result window provides information such as number of code blocks not covered by the test, percentage of code blocks not covered, covered code blocks, and percentage of covered code blocks from the selected assembly.
The result window also provides an option to directly open the source code associated with the listed blocks, and methods to easily navigate and fix.
There are several types of configuration and settings used for testing an application in VS 2010 and each type of test uses its own type of file to store the test related information.
Test Metadata file: This file stores the tests and lists of categories for the tests in an XML format under the file with the extension
.vsmdi. Whenever you create a new test project, this file is created under the
Itemsfolder. The file name is the same as the solution name.
Test Results file: This file contains the results of the tests that were run. This file is created automatically by Visual Studio when any test is run. It has the extension of
Test Run Configuration file: This file contains the settings required for the test run. Using these settings we can define the Data and Diagnostics information to be collected during the test run, deployment files, scripts for setup and cleanup activities before and after the test runs, and the required settings for the Web and unit test runs. This file is created under the solution with the extension
There are other XML files for different test types with some specific extensions such as
This is the new standalone product but it is not part of Visual Studio 2010 Premium. It is part of Visual Studio Test Professional and Visual Studio Ultimate. This is the functional testing tool which provides the ability to create and execute the Manual tests and collect the results. This tool works without Visual Studio but does require a connection to the Team Foundation Server and the Team Project. MTM (Microsoft Test Manager) contains:
Testing Center: This is used for creating Test Plans and creating Test Suites and Test cases for the Test Plans. We can also associate the requirements to the Test Plans. The other features such as running the manual test, capturing the test results and defects, tracking the test results using existing queries and creating custom queries, organizing the test cases and shared steps for test cases, and maintaining the test configurations are supported by Testing Center.
Lab Center: This is used to set up and create lab environments for the test execution. The environments are created using Physical and Virtual machines with a certain set of configurations. Later on, the environment is deployed so that the test is conducted using the environment.
MTM should be connected to the TFS Team Project to create the Test Plans and test cases. The first task on opening MTLM is to connect to the TFS Team Project from the Team Project collection.
The Test Plan window in the Testing Center allows for the creation of new Test Suites, test cases, and adding test cases based on the requirements. Any number of Test cases can be created or added and configured through this window. The first step is to create the Test Plan and Test Suite. Each Test Plan contains a set of Test Suites which helps us to plan the testing effort. For example, we can create a Test Plan for each sprint if we are using agile methodology for the software development. The following screenshot has one Test Plan (MyTestPlan) with Two Test Suites, Add Numbers test and Second Test Suite .
The next step is to create or add Test cases to the Suite. The requirements can be added to the plan and then test cases can be associated with the requirements. In the above example, three requirements are added to the first Test Suite, Add Numbers test, and new test cases are associated with the requirements. These requirements are available in TFS under the Team Project. If we followed the Application lifecycle management and tools available in TFS then we should have the requirements created as part of the requirements phase already.
The creation of a test case involves defining a lot of properties for the test case. Each testing step and the expected result should be defined. The user scenarios, links, and attachments can be associated to the test cases. The test case can be classified under the specific Area path and iteration path for the Team Project in TFS. Other properties such as Assigned To, State, Priority, and Automation Status can be set for the test case.
The Lab center in MTM helps us to create and configure different virtual/physical environments for the test runs, test settings such as defining the roles and configuring the data and diagnostics information for the selected roles, configuring the Test Controllers required for the test, and configuring the test library to store the environment information. The following screenshot shows the Lab Center without any environment:
We can see the details of these configurations later in Chapter 13, Test and Lab Center, which explains the features of Testing Center and Lab Center.
There are lots of new testing features added to Visual Studio 2010, particularly coded UI testing and manual testing using the Test Manager standalone tool. Manual testing is very well structured with lots of options handled separately using the MTM tool. The MTM tool contains Testing Center and Lab Center which help us to maintain the test cases, test configurations and testing environments to simulate the actual user load to test the application performance. This chapter provides the high level information on the tools and techniques available and the new techniques added to Visual Studio 2010. Each of these testing techniques is explained in detail in forthcoming chapters with detailed examples.