How should we reconcile these two facts? Should we go through and convert a bunch of the existing test files to separate method declarations and definitions? Should we let sleeping dogs lie, but aim to follow the style guide in new test code? Should we update the style guide to make an exception for test files?
Regarding the value of this specific rule, I very much agree with the style guide that code -- including and perhaps even _especially_ test code, given how much boilerplate is often mixed in with the few bits of functionality -- is easier to read and understand when declarations and definitions are separate. I have never regretted making this change to a test file. I would be OK with doing away with this rule if it didn't seem to buy anything, but given that I think it's valuable, I'm not happy about the idea of not asking for it to be applied consistently.
On Tue, Jul 23, 2013 at 8:58 PM, Elliot Glaysher (Chromium)
<e...@chromium.org> wrote:
> For a little bit of historical perspective, my recollection is that we have
> prohibitions on inlining was because of rampant inlining of constructors,
> destructors and heavy methods in headers. This bloated our binaries and
> slowed down our compiles as we did the same work over and over again in
> different translation units. These rules come out of the binary size/compile
> time cleanup.
>
>> Regarding the value of this specific rule, I very much agree with the
>> style guide that code -- including and perhaps even _especially_ test code,
>> given how much boilerplate is often mixed in with the few bits of
>> functionality -- is easier to read and understand when declarations and
>> definitions are separate. I have never regretted making this change to a
>> test file. I would be OK with doing away with this rule if it didn't seem
>> to buy anything, but given that I think it's valuable, I'm not happy about
>> the idea of not asking for it to be applied consistently.
> That said, I agree with the broad strokes of this from a pure aestheticI agree with Ilya, the separation is pretty good when it's between
> point of view. I do find a separation of a separation of declarations and
> definitions to be easier to read in general.
>
header (declaration) and source (definition/implementation), but not
(IMO) in test file (read source file). Because you are basically
typing the same boilerplate twice (for how much benefit?).
I can be convinced otherwise though ;)
--
Thiago
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
I actually land pretty strongly on the side of inlining the test fixture code inside unittests.
I actually land pretty strongly on the side of inlining the test fixture code inside unittests. From a consistency perspective, the prevailing convention is to inline (did a quick sanity check by examining about 40 random test files...only 3 had definitions separated out).
Note that in most cases the method bodies are small, and are arguably easier to read inline. With lots of long methods I'd separate out the implementation, leaving the judgment up to the change author and reviewer.
On Tue, Jul 23, 2013 at 5:22 PM, Albert J. Wong (王重傑) <ajw...@chromium.org> wrote:
I actually land pretty strongly on the side of inlining the test fixture code inside unittests.Meaning, change the style guide to specifically mandate that this happens?
Also, you mentioned consistency; I assume you like this for non-consistency reasons as well, but you didn't detail that.
All fixtures follow a very specific API formula of having some combination of Constructor, Destructor, SetUp or TearDown methods. Fixture state is exposed to TEST_Fs as protected member variables (also a style guide violation).
Digression: this is also why I dislike test harnesses that inherit from testing::Test; it's mixing something that's acting like a symbol context with something that's acting like an object.
As for actual readability degradation, if you think of a source file as a piece of technical writing, then in a unittest the main content is in the TEST_F. The more lines of non-TEST_F code there are, the less clear the test is IMO. Adding extra lines of boilerplate feels like it's distracting from the main thrust of the file.
For example, in autofill_interactive_uitest.cc (to return again to the actual CL that inspired this thread), there is just one (disabled!) TEST_F taking up ~25 lines of the 360-line file. Everything else is support. I'm not sure de-inlining the support classes makes a categorical difference to the "main thrust" of this test.
Thanks for this reply. I'm not sure I followed everything perfectly, but it was very useful.All fixtures follow a very specific API formula of having some combination of Constructor, Destructor, SetUp or TearDown methods. Fixture state is exposed to TEST_Fs as protected member variables (also a style guide violation).What about classes that have methods that do non-trivial work, i.e. something other than just increment some members, call through to the underlying class being tested, or provide simple access to state? Are those cases where you feel differently?
Digression: this is also why I dislike test harnesses that inherit from testing::Test; it's mixing something that's acting like a symbol context with something that's acting like an object.I'm not clear on what you're calling out here. I assume "harnesses" means something different than "fixtures", i.e. you're not complaining about all the classes that inherit from testing::Test to do SetUp() and TearDown(). Are you talking about things like InProcessBrowserTest or something?
As for actual readability degradation, if you think of a source file as a piece of technical writing, then in a unittest the main content is in the TEST_F. The more lines of non-TEST_F code there are, the less clear the test is IMO. Adding extra lines of boilerplate feels like it's distracting from the main thrust of the file.FWIW, this is part of why I always put divider lines between the test support structure and the actual tests. If you want to read the tests, this makes it easy to find them, and the presence or absence of a separated class definition above the divider seems like it has no distracting effect. I don't know if you agree though.I also often run into cases where the test "base class(es)" is(are) far larger than the tests. For example, in autofill_interactive_uitest.cc (to return again to the actual CL that inspired this thread), there is just one (disabled!) TEST_F taking up ~25 lines of the 360-line file. Everything else is support. I'm not sure de-inlining the support classes makes a categorical difference to the "main thrust" of this test.
--
I just this thread. I agree with the comments that not-inlining in test files isn't very useful and just adds more boilerplate, so I'm glad to see that we have come to a consensus there.However I don't buy the reasons not to do it in non-test files. I think it's also more redundant copy and paste, especially for small classes/methods. If that code is later moved to a header, which I've sen many times, I've not yet seen one example where someone didn't actually split it into a .h and .cc. As for consistency, one could go both ways (i.e. in all .cc files, test or not, we can inline methods). Lastly, regarding "class API", when a class is used in one cc file, this is usually not much of an issue as there's just one caller.I'm not saying we need to have a hard rule against this (i.e. saying always inline, or never inline). Like all things, different people have different preferences. But it seems like we should just treat all .cc fils the same, test or non-test.
However I don't buy the reasons not to do it in non-test files. I think it's also more redundant copy and paste, especially for small classes/methods. If that code is later moved to a header, which I've sen many times, I've not yet seen one example where someone didn't actually split it into a .h and .cc. As for consistency, one could go both ways (i.e. in all .cc files, test or not, we can inline methods). Lastly, regarding "class API", when a class is used in one cc file, this is usually not much of an issue as there's just one caller.
I'm not saying we need to have a hard rule against this (i.e. saying always inline, or never inline). Like all things, different people have different preferences.
But it seems like we should just treat all .cc fils the same, test or non-test.
PK
That also means that I wouldn't want to see changes to convert one style to another as part of cleanups or nearby changes.
PK