unittesting_share

Get Started. It's Free
or sign up with your email address
Rocket clouds
unittesting_share by Mind Map: unittesting_share

1. Unit Testing Introduction

1.1. what makes a good unit testing?

1.1.1. It should be automated and repeatable.

1.1.2. It should be easy to implement.

1.1.3. Once it’s written, it should remain for future use.

1.1.4. Anyone should be able to run it.

1.1.5. It should run at the push of a button.

1.1.6. It should run quickly.

1.2. compared with integration testing

1.2.1. Untitled

1.2.2. integration testing characteristic

1.2.2.1. integration testing can be further categorized based on different integration level

1.2.2.1.1. level 1: module level integration testing

1.2.2.1.2. level 2: component level integration testing

1.2.2.1.3. level 3: system level integration testing

1.2.2.2. Untitled

1.2.2.2.1. Untitled

1.2.3. difference

1.2.3.1. an integration test exercises many units of code that work together to evaluate one or more expected results from the software, whereas a unit test usually exercises and tests only a single unit in isolation.

1.3. core techniques: stub and mock

1.3.1. Stub

1.3.1.1. Untitled

1.3.1.1.1. An external dependency is an object in your system that your code under test interacts with, and over which you have no control. (Common examples are filesystems, threads, memory, time, and so on.)

1.3.1.1.2. testing type: state-based testing

1.3.1.1.3. example

1.3.1.1.4. Here are some techniques for breaking dependencies:

1.3.2. Mock

1.3.2.1. Untitled

1.3.2.1.1. testing type: interaction testing

1.3.2.1.2. compared with stub

1.3.2.1.3. suggestion: one mock object per test

1.3.3. Fake

1.3.3.1. Untitled

1.3.4. isolation framework

1.3.4.1. Untitled

1.3.4.1.1. Untitled

1.3.4.2. available isolation framework for c++: mockpp, google c++ mock framework

1.3.4.3. how to use a isolation framework?

1.3.4.3.1. gmock

1.4. do we really need unit testing?

1.4.1. requirement: testable design

1.4.1.1. why request testable design?

1.4.1.1.1. Tests against our software are another type of user. That user has strict demands for our software, but they all stem from one mechanical request: testability. That request can influence the design of our software in various ways, mostly for the better.

1.4.1.2. guidelines and benefits

1.4.1.2.1. Make methods virtual by default.

1.4.1.2.2. Use interface-based designs

1.4.1.2.3. Make classes nonsealed by default.

1.4.1.2.4. Avoid instantiating concrete classes inside methods with logic. Get instances of classes from helper methods, factories, Inversion of Control containers such as Unity, or other places, but don’t directly create them.

1.4.1.2.5. Avoid direct calls to static methods. Prefer calls to instance methods that later call statics.

1.4.1.2.6. Avoid constructors and static constructors that do logic.

1.4.1.2.7. Separate singleton logic from singleton holder.

1.4.1.3. disadvantages:

1.4.1.3.1. amount of work

1.4.1.3.2. complexity

1.4.1.3.3. Exposing sensitive IP

1.4.1.3.4. Sometimes you can’t

1.4.1.4. when tastable design break down

1.4.1.4.1. By following testable object-oriented design principles, you might get testable designs as a byproduct, but testability should not be a goal in your design.

1.4.1.4.2. There are tools that can help replace dependencies (for example, Typemock Isolator in .NET code) without needing to refactor it for testability.

1.4.2. tough questions when Integrating unit testing into the organization

1.4.2.1. How much time will this add to the current process?

1.4.2.1.1. When asking about time, team leads may really be asking, “What should I tell my project manager when we go way past our due date?” They may actually think the process is useful but are looking for ammunition for the upcoming battle. They may also be asking the question not in terms of the whole product, but in terms of specific feature sets or functionality. A project manager or customer who asks about timing, on the other hand, will usually be talking in terms of full product releases. Because different people care about different scopes, the answers you give them may vary. For example, unit testing can double the time it takes to implement a specific feature, but the overall release date for the product may actually be reduced. To understand this, let’s look at a real example I was involved with.

1.4.2.2. Will my QA job be at risk because of this?

1.4.2.2.1. Unit testing doesn’t eliminate QA-related jobs. QA engineers will receive the application with full unit-test suites, which means they can make sure all the unit tests pass before they start their own testing process. Having unit tests in place will actually make their job more interesting. Instead of doing UI debugging (where every second button click results in an exception of some sort), they will be able to focus on finding more logical (applicative) bugs in real-world scenarios. Unit tests provide the first layer of defense against bugs, and QA work provides the second layer—the user’s acceptance layer. As with security, the application always needs to have more than one layer of protection. Allowing the QA process to focus on the larger issues can produce better applications. In some places, QA engineers write code, and they can help write unit tests for the application. That happens in conjunction with the work of the application developers and not instead of it. Both developers and QA engineers can write unit tests.

1.4.2.3. How do we know this is actually working?

1.4.2.3.1. [click or expand me to see figure] To determine whether your unit testing is working, create a metric of some sort, as discussed in section 8.2.5. If you can measure it, you’ll have a way to know; plus, you’ll feel it. Figure for this node [click me to see] shows a sample test-code-coverage report (coverage per build). Creating a report like this, by running a tool like NCover for .NET automatically during the build process, can demonstrate progress in one aspect of development. Code coverage is a good starting point if you’re wondering whether you’re missing unit tests.

1.4.2.4. Is there proof that unit testing helps?

1.4.2.4.1. There aren’t any specific studies I can point to on whether unit testing helps achieve better code quality. Most related studies talk about adopting specific agile methods, with unit testing being just one of them. Some empirical evidence can be gleaned from the web, of companies and colleagues having great results and never wanting to go back to a code base without tests. A few studies on TDD can be found at http://biblio.gdinwiddie.com/ biblio/StudiesOfTestDrivenDevelopment.

1.4.2.5. Why is the QA department still finding bugs?

1.4.2.5.1. The job of a QA engineer is to find bugs at many different levels, attacking the application from many different approaches. Usually a QA engineer will perform integration-style testing, which can find problems that unit tests can’t. For example, the way different components work together in production may point out bugs even though the individual components pass unit tests (which work well in isolation). In addition, a QA engineer may test things in terms of use cases or full scenarios that unit tests usually won’t cover. That approach can discover logical bugs or acceptance-related bugs and is a great help to ensuring better project quality. A study by Glenford Myre showed that developers writing tests were not really looking for bugs, and so found only half to two-thirds of the bugs in an application. Broadly, that means there will always be jobs for QA engineers, no matter what. Although that study is 30 years old, I think the same mentality holds today, which makes the results still relevant today.

1.4.2.6. We have lots of code without tests: where do we start?

1.4.2.6.1. Studies conducted in the 1970s and 1980s showed that, typically, 80 percent of the bugs are found in 20 percent of the code. The trick is to find the code that has the most problems. More often than not, any team can tell you which components are the most problematic. Start there. You can always add some metrics relating to the number of bugs per class. Testing legacy code requires a different approach than when writing new code with tests. See chapter 9 for more details.

1.4.2.7. We work in several languages: is unit testing feasible?

1.4.2.7.1. Sometimes tests written in one language can test code written in other languages, especially if it’s a .NET mix of languages. You can write tests in C# to test code written in VB.NET, for example. Sometimes each team writes tests in the language they develop in: C# developers can write tests in C# using NUnit or MbUnit, and C++ developers can write tests using one of the C++ oriented frameworks, such as CppUnit. I’ve also seen solutions where people who wrote C++ code would write managed C++ wrappers around it and write tests in C# against those managed C++ wrappers, which made things easier to write and maintain.

1.4.2.8. What if we develop a combination of software and hardware?

1.4.2.8.1. If your application is made of a combination of software and hardware, you need to write tests for the software. Chances are, you already have some sort of hardware simulator, and the tests you write can take advantage of this. It may take a little more work, but it’s definitely possible, and companies do this all the time.

1.4.2.9. How can we know we don’t have bugs in our tests?

1.4.2.9.1. You need to make sure your tests fail when they should and pass when they should. Test-driven development is a great way to make sure you don’t forget to check those things.

1.4.2.10. My debugger shows that my code works: why do I need tests?

1.4.2.10.1. You may be sure your code works fine, but what about other people’s code? How do you know it works? How do they know your code works and that they haven’t broken anything when they make changes? Remember that coding is just the first step in the life of the code. Most of its life, the code will be in maintenance mode. You need to make sure it will tell people when it breaks, using unit tests. A study held by Curtis, Krasner, and Iscoe showed that most defects don’t come from the code itself, but result from miscommunication between people, requirements that keep changing, and a lack of application domain knowledge. Even if you’re the world’s greatest coder, chances are that, if someone tells you to code the wrong thing, you’ll do it. And when you need to change it, you’ll be glad you have tests for everything else to make sure you don’t break it.

1.4.2.11. Must we do TDD-style coding?

1.4.2.11.1. TDD is a style choice. I personally see a lot of value in TDD, and many people find it productive and beneficial, but others find that writing the tests after the code is good enough for them. You can make your own choice.

1.4.3. working with legacy code

1.4.3.1. problems

1.4.3.1.1. It was difficult to write tests against existing code.

1.4.3.1.2. It was next to impossible to refactor the existing code (or there was not enough time to do it).

1.4.3.1.3. Some people didn’t want to change their designs.

1.4.3.1.4. Tooling (or lack of tooling) was getting in the way.

1.4.3.1.5. It was difficult to determine where to begin.

1.4.3.2. strategies

1.4.3.2.1. Where do you start adding tests?

1.4.3.2.2. Choosing a selection strategy.

1.4.3.2.3. Writing integration tests before refactoring

1.4.3.2.4. Important tools for legacy code unit testing

2. CppUnit framework

2.1. definition

2.1.1. History of SUnit

2.1.1.1. Untitled

2.1.2. CppUnit is the C++ version of SUnit

2.2. cppunit class analysis

2.2.1. analysis

2.2.1.1. Untitled

2.2.2. classes for management/organization

2.2.2.1. Test

2.2.2.2. TestLeaf

2.2.2.3. TestComposite

2.2.2.4. TestSuite

2.2.2.5. TestPath

2.2.3. classes for testing

2.2.3.1. TestCase

2.2.3.2. TestCaller

2.2.3.3. TestFixture

2.2.3.4. TestRunner

2.2.3.5. TestListener

2.2.3.6. TestResult

2.2.3.6.1. TestResult manages the TestListener (registration and event dispatch), as well as the stop flag indicating if the current test run should be interrupted.

2.2.3.7. TestResultCollector

2.2.3.7.1. A TestResultCollector is a TestListener which collects the results of executing * a test case. It is an instance of the Collecting Parameter pattern

2.2.4. UML class diagram

2.2.4.1. Untitled

2.3. how to coding

2.3.1. Method1: TestCase + TestResult + TestResultCollector + TextOutputter

2.3.1.1. Untitled

2.3.2. Method2: TestCase + TestRunner

2.3.2.1. Untitled

2.3.3. Method3: TestCaller + TestResult

2.3.3.1. Untitled

2.3.4. Method4: TestCase + TestSuite(Macro) + TestRunner + Registry

2.3.4.1. Untitled

2.3.5. Method5: TestCaller + TestSuite (no Macro) + Test Runner + no Registry

2.3.5.1. Untitled

2.3.6. Method6: TestFixture + TestSuite(Macro) + TestRunner + Registry

2.3.6.1. This is the most recommended to write test code using CppUnit

2.3.6.2. example

2.3.6.2.1. Untitled

2.3.7. Other coding notes

2.3.7.1. understand the pointers in cppunit

2.3.7.1.1. Untitled

2.3.7.2. customize the output format

2.3.7.2.1. Untitled

2.3.7.3. track the testing time

2.3.7.3.1. Untitled

2.3.7.4. macro's

2.3.7.4.1. Macro used to automatically generate TestCaller and TestSuite

2.3.7.4.2. Macro to automatically add fixture suite to registry

2.4. how to compile/build

2.4.1. compile with cppunit

2.4.1.1. g++ <C/C++ file> -I$CPPUNIT_HOME/include –L$CPPUNIT_HOME/lib -lcppunit

2.5. more information

2.5.1. cppunit sourceforge index

2.5.2. cppunit documentation

2.5.3. cppunit wiki

3. CppUnit in SeP system

3.1. to be tested project

3.1.1. Untitled

3.1.1.1. IDFC_app

3.1.2. project description

3.1.2.1. This is exactly the same project that NOBE team is developing, no need to add any change to this project.

3.2. testing framework project

3.2.1. project name

3.2.1.1. Untitled

3.2.2. project description

3.2.2.1. It is a library project. Its output can static or dynamic library.

3.2.2.2. Untitled

3.2.2.3. In order to be used by SeP projects, it is imported and configured as a QNX project in QNX Momentics IDE

3.2.2.4. Once it is built and the library which it generates is copied to the required place (which in our case is $cppunit_root_folder/lib/ ), no need to build it a second time.

3.2.3. project download

3.2.3.1. click me to download

3.3. testing projects

3.3.1. project 1

3.3.1.1. project name

3.3.1.1.1. Untitled

3.3.1.2. depend on projects

3.3.1.2.1. to be tested project

3.3.1.2.2. testing framework project

3.3.1.3. project description

3.3.1.3.1. this project tests only the bexphandler module of the IDCF_app application

3.3.1.3.2. this project uses stub/mock techniques to isolate the bexphandler module code under test.

3.3.1.4. project files layout

3.3.1.4.1. Untitled

3.3.1.5. project settings

3.3.1.5.1. compile_inc

3.3.1.5.2. compile_src

3.3.1.5.3. compile_macro

3.3.1.5.4. link_libraries

3.3.1.6. code analysis

3.3.1.6.1. code under test (CBEXPHandler::sendMsgToMCS())

3.3.1.6.2. testing code

3.3.1.7. project download

3.3.1.7.1. click me to download

3.3.2. project2

3.3.2.1. project name

3.3.2.1.1. Untitled

3.3.2.2. depend on projects

3.3.2.2.1. to be tested project

3.3.2.2.2. testing framework project

3.3.2.3. project description

3.3.2.3.1. This project does not use any of the stub/mock techniques, it is kind of integration testing rather than unit testing. All the code under test and its dependency are real code.

3.3.2.4. project files layout

3.3.2.4.1. Untitled

3.3.2.5. project settings

3.3.2.5.1. compile_inc

3.3.2.5.2. compile_src

3.3.2.5.3. compile_macro

3.3.2.5.4. link_libraries

3.3.2.6. code analysis

3.3.2.6.1. code under test (CDeviceRegistrationHost::CDEVREGHost_removeClientFromClientList())

3.3.2.6.2. testing code

3.3.2.7. project download

3.3.2.7.1. click me to download

3.4. resources

3.4.1. empty implemented stub code for IDFC and LTA component download

4. how to navigate this guidence

4.1. Navigation in Map

4.1.1. To move the cursor up, down, left or right, use arrow keys.

4.1.2. To move to the top of the current subtree, press PageUp.

4.1.3. To move to the bottom of the current subtree, press PageDown.

4.1.4. To move to the central node, press Escape.

4.1.5. To move back and forth in the history of visited nodes use Navigate > Previous (or press Alt + Left), or Navigate > Next (or press Alt + Right), respectively.

4.1.6. For visiting all nodes of a map conveniently use Navigate > Next node (Ctrl + Alt + Right) and Navigate > Previous node (Ctrl + Alt + Left).

4.1.7. If you want nodes to be folded again after visiting them use the menu choices "Navigate > Next node (fold)" (or press Ctrl + Alt + Shift + Right), and "Navigate > Previous node (fold)" (or press Ctrl + Alt + Shift + Left).

4.1.8. By default nodes are selected by placing the mouse cursor over a node (after a short delay).

4.1.9. This can be changed via Tools > Preferences > Behaviour > Selection Method

4.1.10. Available selection methods are "By Click", "Direct", and "Delayed" (default)

4.2. Selecting multiple nodes

4.2.1. To select multiple nodes, hold Ctrl or Shift while clicking.

4.2.2. To add single nodes to already selected nodes, hold Ctrl when clicking.

4.2.3. To select a continuous range of nodes, hold Shift when clicking, or hold Shift while moving around with arrow keys.

4.2.4. To select a complete subtree, use Ctrl + Shift + A, or hold Shift while moving with arrow keys from a node to its parent, or hold Alt Gr while clicking.

4.2.5. To cancel the selection of multiple nodes, click on the map background or on an unselected node.

4.3. Folding and unfolding

4.3.1. A folded node is marked with a small circle attached in the direction farthest from the root node.

4.3.2. To fold a node use Toggle > Folded or press the Space bar.

4.3.3. To unfold a node use Toggle > Folded, or press the Space bar, or press the arrow key in the direction of unfolding.

4.3.4. To fold or unfold nodes in levels, hold Alt while using mousewheel, or press Alt + PageUp or Alt + PageDown. With large maps, use this function carefully; it may lead to memory problems.

4.3.5. To unfold all nodes use Navigate > Unfold All, or press the circled plus button in the main toolbar, or press Alt + End.

4.3.6. To fold all nodes use Navigate > Fold All, or click the circled minus button in the main toolbar, or press Alt + Home.

4.4. Scrolling the map

4.4.1. To scroll the map, drag the background and move it around, or use the mouse wheel. To scroll horizontally with mouse wheel, hold the Shift key or, on some operating systems, hold one of the mouse buttons.

4.5. Zooming

4.5.1. The View menu includes the commands Zoom In, Zoom Out, and Zoom to Fit to Page.

4.5.2. The main toolbar contains a zoom control field in with presets for various percentages. These settings may also be chosen by pressing Alt + up or down arrow.

4.5.3. On some operating systems you may zoom by using the mouse wheel while holding the Ctrl key.

4.6. Searching and Filtering

4.6.1. You can search and filter nodes based on its text, icons, creation/modification time, position, priority, connectors, hyperlinks, notes and attributes.

4.6.2. To find text or other criteria in a node and all its descendant nodes, use Edit > Find... or press Ctrl + F.

4.6.3. To find the next match of your previous search, use Edit > Find Next or press Ctrl + G.

4.6.4. The search is a breadth-first search. In other words, the deeper a node, the later it will be found.

4.6.5. This search method currently works only on the currently-selected node and its descendants. In the future there may be an option to continue the search through the rest of the map.

4.6.6. To search the entire map for all occurrences of matching text, with an optional to supply replacement text, use "Edit > Find and Replace..." A similar method can be used across all currently-open maps by choosing "Edit >Find and Replace in all maps."

4.6.7. You can build filters to see only a subset of map nodes. Use the Filter Toolbar or the Filter Menu.

5. CppUnit Framework License

5.1. GNU Lesser General Public License

5.1.1. GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.