Initialize C++ unit test fixture in constructor or in SetUp?

4,269 views
Skip to first unread message

Anthony Berent

unread,
Nov 27, 2015, 6:15:33 AM11/27/15
to chromium-dev
This comes from a comment I received in a code review.

In googletest there are two ways of initializing a test fixture before running each test. One can either put the initialization code in the test fixture constructor, or write a SetUp function. In both cases the initialization code is run before every test.

The googletest documentation (https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#should-i-use-the-constructordestructor-of-the-test-fixture-or-the-set-uptear-down-function) advises putting the initialization code in the constructor, except in a few special cases (which don't seem relevant for any of our tests). Most of the unit tests in our code base, however, seem to put the initialization code in SetUp, and have empty constructors.  Where should we put the initialization code in new test fixtures? Why?

Peter Kasting

unread,
Nov 27, 2015, 6:55:00 AM11/27/15
to Anthony Berent, chromium-dev
On Fri, Nov 27, 2015 at 3:14 AM, Anthony Berent <abe...@chromium.org> wrote:
The googletest documentation (https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#should-i-use-the-constructordestructor-of-the-test-fixture-or-the-set-uptear-down-function) advises putting the initialization code in the constructor, except in a few special cases (which don't seem relevant for any of our tests). Most of the unit tests in our code base, however, seem to put the initialization code in SetUp, and have empty constructors.  Where should we put the initialization code in new test fixtures? Why?

If you don't have a strong reason to choose one, follow the googletest guidelines.

Much of our test code was written by folks like me who at the time didn't necessarily know the guidelines or understand the rules on when what things ran.  We saw people using SetUp() and just copied it.  Don't treat that as a mandate to continue the trend :)

PK 

Ilya Sherman

unread,
Nov 28, 2015, 1:03:58 AM11/28/15
to Peter Kasting, Anthony Berent, chromium-dev
I think it doesn't matter too much either way, but I generally prefer constructors, for at least these two reasons:
(1) I don't need to remember to call the superclass's SetUp() method.
(2) I can initialize data members once, in the constructor, rather than needing a pointer that I set to null in the constructor and then actually set in the SetUp() method.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Colin Blundell

unread,
Nov 30, 2015, 3:31:47 AM11/30/15
to ishe...@chromium.org, Peter Kasting, Anthony Berent, chromium-dev
content::RenderViewHostTestHarness does most of its setup in SetUp(); e.g., that is where its BrowserContext, WebContents, and TestBrowserThreadBundle instances are instantiated. Presumably, most tests that subclass this class (or subclass ChromeRenderViewHostTestHarness, which is itself a subclass of this class) must necessarily do their own setup in their SetUp() methods as a consequence.

Peter Kasting

unread,
Nov 30, 2015, 4:28:02 PM11/30/15
to Colin Blundell, Ilya Sherman, Anthony Berent, chromium-dev
On Mon, Nov 30, 2015 at 12:30 AM, Colin Blundell <blun...@chromium.org> wrote:
content::RenderViewHostTestHarness does most of its setup in SetUp(); e.g., that is where its BrowserContext, WebContents, and TestBrowserThreadBundle instances are instantiated. Presumably, most tests that subclass this class (or subclass ChromeRenderViewHostTestHarness, which is itself a subclass of this class) must necessarily do their own setup in their SetUp() methods as a consequence.

If this ties the hands of anyone, I have no problem refactoring to make this class use the constructor instead of SetUp().

PK 

Robert Sesek

unread,
Nov 30, 2015, 4:41:06 PM11/30/15
to Peter Kasting, Colin Blundell, Ilya Sherman, Anthony Berent, chromium-dev
The one useful property of using SetUp() is that you can use ASSERT_ macros to fail tests early, whereas the constructor must successfully complete. I use SetUp() whenever I have common initialization that may fail, and the ctor otherwise. That doesn't appear to be an issue in RenderViewHostTestHarness, though.

rsesek / @chromium.org 

Reply all
Reply to author
Forward
0 new messages