Google Test only executing one test?
30 March, 2011 § 1 Comment
Earlier today while pair-programming, Angie and I ran into an issue where Google Test was only executing one unit test of the 150 or so in our test suite. We weren’t sure what the cause could be. We switched machines and all the unit tests ran fine on my machine.
We first checked the WinMain entry point to see if some configuration flag of GTest had been accidentally flipped. A quick diff showed us that nothing had changed.
So what could be differentiating Angie’s computer from mine? Well it turns out that Angie really enjoys using keyboard shortcuts and macros to help her do her work. A couple weeks ago I showed her some of the Visual Studio macros that are used in developing for Chromium. Angie saw the list of macros and quickly installed the “Alternate between source and header file”, as well as the “Run the currently selected google test”.
It turns out that the “Run the currently selected google test” works by adjusting the command line arguments that are passed to the GTest executable. This argument sets a filter on the test runner to only run the tests that match the given filter, which in this case happens to be the name of the currently selected test.
As the Jing states, simply clearing out the command argument fixed our problem. If you’re using the macro mentioned earlier, you can also place your cursor outside of a specific test case, run the macro, and the filter will be cleared.
I hope this post comes in handy for anyone else that got stuck in our position.
Initializing an array in C++
16 June, 2010 § 6 Comments
Most people know about member initialization lists in C++. Initialization lists allow you to initialize a variable when the class is instantiated, versus assigning a value within the constructor.
Have you ever tried to initialize an array? Many websites will tell you that this is not possible. In fact, if you try this you’ll get a compiler error:
class array { public: bool vars[2]; array() : vars[0](true), vars[1](true) {} };
BUT, if all you want to do is zero-initialize the array then you’re in luck! Simply place parens after the array and the array will be zero-initialized. Try out the code below:
#include <iostream> class arrayInit { public: bool vars[2]; arrayInit() : vars() {} }; class array { public: bool vars[2]; array() {} }; int main() { arrayInit a; std::cout << "a.vars[0] = " << a.vars[0] << std::endl; std::cout << "a.vars[1] = " << a.vars[1] << std::endl; array b; std::cout << "b.vars[0] = " << b.vars[0] << std::endl; std::cout << "b.vars[1] = " << b.vars[1] << std::endl; }
Using code like this in Visual Studio can generate warning C4351 because the behavior is different from previous versions of VC++. Here is the documentation from MSDN:
Compiler Warning (level 1) C4351
new behavior: elements of array ‘array’ will be default initialized
When an array is in a constructor’s member initialization list, the elements of the array will be default initialized. In previous versions of Visual C++, when an array was in a constructor’s member initialization list, the elements of the array may not have been default initialized in some cases.
If the array’s element type does not have a constructor, the elements of the array will be initialized with the corresponding zero representation for that type.
C4351 means that you should inspect your code. If you want the compiler’s previous behavior, remove the array from the constructor’s member initialization list.
If you want the new behavior, which is likely, because the array was explicitly added to the constructor’s member initialization list, use the warning pragma to disable the warning. The new behavior should be fine for most users.
One situation where the new behavior can result in unexpected behavior is when placement new is used to construct the object that has the array as a member, and the program depends on the contents that the memory (for the elements of the default initialized array) had before the call to placement new. In this case, the older compiler would have left the contents of memory unchanged, but the new behavior will cause default initialization of the array elements, overwriting the original contents in memory.
Finding how a header file gets included
6 May, 2010 § 2 Comments
Have you ever had a header file generate warnings that is not explicitly part of your Visual Studio solution?
Recently I’ve been working on fixing static analysis warnings reported by Microsoft’s PREfast static analysis tool for C++. I ran in to an issue though with some of the Microsoft Windows SDK v6.0 headers. One file, aptly named `strsafe.h
`, can be the cause for tons of warnings in a build.
I looked around and found that the Windows SDK team is fully aware of the problem. They recommend wrapping the include for strsafe.h
with pragmas, like so:
#include <CodeAnalysis/warnings.h> #pragma warning(push) #pragma warning(disable: ALL_CODE_ANALYSIS_WARNINGS) #include <strsafe.h> #pragma warning(pop)
So the first thing I did was to search through my code and find out who what included strsafe.h
. But it turns out that no file explicitly included it. I figured that it must get included from another include file.
To find out what files are included in your build, you can turn on /showIncludes
through the Project Properties ➨ Configuration Properties ➨ C/C++ ➨ Advanced ➨ Show Includes
/showIncludes
prints out a tree of all of the files that get included in when the project is built. Using this, I was able to find which SDK files we included that ended up including strsafe.h.
This process took me about a half hour in total from turning the compiler flag on, performing a rebuild, narrowing down the includes, and wrapping them with pragmas. I still got a nasty taste in my mouth for suppressing the warnings, but getting rid of them cut out a lot of noise surrounding actual warnings that are more pressing.
Unit testing MFC with MSTest
6 May, 2009 § 20 Comments
Visual Studio 2008 offers the built in ability to write unit tests in C# by creating a Test Project. This same feature applies to managed C++, otherwise known as C++/CLI. If you are working on a project in MFC and would like to get the same unit test integration that is built directly in to Visual Studio, there is a way. Here are the steps you will have to follow:
- Create a C++ Test project within your solution.
- Open up the Properties of the project and change the Common Language Runtime support from /clr:safe to /clr. This will allow you to execute code from both C++/CLI and simple C++.
- Set the project to link to MFC using a shared DLL. You cannot compile with both /clr and statically linking to MFC.
- Edit the test project’s dependencies and add a dependency on the MFC project that you would like to unit test.
You should be all good here, except for one large gotcha. The unit test project will have its own instance of CWinApp declared. If the MFC project that you would like to test against also has its own instance of CWinApp, then everything will get confused and the tests won’t start. To solve this, you will have to create a separate MFC DLL project and move your code to this project. Your test project should now have a dependency on this new MFC DLL project, and not your previous one. If you would still like your application to produce a single executable, just make sure that the previous project statically links against the MFC DLL that you have just created.
Let me know if you have any questions. I’ve spent the last couple days getting this scenario to work.
(I’m using GoogleMock with my unit tests, and I think that the combination of MSTest and GoogleMock is perfect. The integration with Visual Studio that MSTest provides, and the ease to make mocks with GoogleMock makes writing C++ unit tests a walk in the park. I should be putting up a simple tutorial on using GoogleMock in the future.)
Trials and tribulations of building Google Chrome with Visual Studio 2008
25 March, 2009 § Leave a comment
You’ve downloaded the Google Chrome tarball from their website and are all ready to build it and play around with the code. This is what I was ready to do. The IDE that I have installed on my machine is Visual Studio 2008 SP1, which isn’t supported yet for the Chromium solution. Here are the steps that I have taken so far, they may be helpful if you are in my steps:
By the way, my download was revision 10080.
- In MathExtras.h, you’ll have to comment out the line #include <xmath.h> from the WebKit\WebCore file.
- Remove all the inline keywords from the Glue project
- Add the RAW_KEY_DOWN value to the WebInput enumeration.
This is where I sit now. I’ve got about 150 errors when I build. Some of the errors mention missing files. When I get a chance I’m planning on just syncing up my source with the latest and hoping that will fix some of the missing files. When I get it all working, I’ll add a post with steps on how to build Google Chrome with Visual Studio 2008 SP1.