<div dir="ltr"><div dir="ltr"> </div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, May 30, 2020 at 7:38 PM Amos Jeffries <<a href="mailto:squid3@treenet.co.nz" target="_blank">squid3@treenet.co.nz</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 31/05/20 5:27 am, Francesco Chemolli wrote:<br>
> Hi all,<br>
>    starting from a PR in a conversation with Alex about our current<br>
> approach to unit testing being painful, I've checked what alternatives<br>
> would we have and how practical would they be.<br>
> <br>
> An easy first option would be googletest/googlemock.<br>
> <br>
> On a lazy afternoon, I've tried seeing how useful/painful it would be to<br>
> try it, by porting one test over - it's quite trivial and doesn't<br>
> require mocking, so I'll try a more complicated one next - to start a<br>
> conversation about the topic.<br>
> <br>
> You can find the test branch at <a href="https://github.com/kinkie/squid/tree/gtest" rel="noreferrer" target="_blank">https://github.com/kinkie/squid/tree/gtest</a> .<br>
> I've only touched two files, a newly-created src/tests/testMemGtest and<br>
> src/Makefile.am .<br>
> <br>
> The output from the test run is at <a href="https://paste.ubuntu.com/p/3sgTDN7rNm/" rel="noreferrer" target="_blank">https://paste.ubuntu.com/p/3sgTDN7rNm/</a><br>
> <br>
> What do you think?<br>
> <br>
> My initial thoughts:<br>
> - it is somewhat simpler and more powerful than cppunit<br>
> - setting the test environment up is easy but at this time it can only<br>
> be done from source. Adding it to the build farm images is straightforward<br>
<br>
That is a problem. The unit tests are run by pretty much everyone<br>
building Squid.<br></blockquote><div><br></div><div>We should be able to bundle gtest if needed; we only distribute in source form and it wouldn't be part of distfiles so it shouldn't be a problem downstream either, I believe </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
It is not a complete blocker, but having a process more complex than<br>
simple dependency install does pose a relatively major hurdle that any<br>
framework has to get over to be of much utility.<br>
<br>
<br>
<br>
> - the license is BSD 3-clause new<br>
> (<a href="https://github.com/google/googletest/blob/master/LICENSE" rel="noreferrer" target="_blank">https://github.com/google/googletest/blob/master/LICENSE</a>) <br>
> - googlemock promises to be vastly superior to our current approach<br>
<br>
Where are you seeing evidence of this?<br></blockquote><div><br></div><div>Also including answer on Alex' question:</div><div>- <a href="https://stackoverflow.com/questions/7922289/googletest-vs-cppunit-the-facts">https://stackoverflow.com/questions/7922289/googletest-vs-cppun it-the-facts</a><br></div><div>- trivial but it builds up: not generally necessary to have .h and .cc for simple cases</div><div>- comparison table: <a href="https://socialcompare.com/en/comparison/c-unit-testing-framework">https://socialcompare.com/en/comparison/c-unit-testing-framework</a></div><div>- gmock/gtest is used in broadly-used projects (e.g. chromium) - I'm not sure </div><div><br></div><div><br></div><div>So far I'm basing on documentation, found at <a href="https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md" target="_blank">https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md</a> .</div><div>I see: </div><div>- a more structured approach to mocking, and more infrastructure to do it<br></div><div>- ON_CALL and EXPECT_CALL patterns to define actions and expectations on class methods (method called once / called multiple times). This can also allow to change the behaviour of a mocked object on different tests without having to remock it all</div><div>- matchers on called methods</div><div>- moched methods can different return values depending on arguments, and check for complex sequences of calls to methods (call a() with some arguments, then either b() or c(), if it's c() must be followe by d() </div><div>- for object, the concept of "uninteresting calls" that get ignored, and can be defaulted</div><div></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
The main issue we have with cppunit itself is that when a test fails it<br>
is not clear from the output which assertion occurred, nor why. One is<br>
left having to try and trigger the unit failure again manually and gdb<br>
from there.<br>
<br>
This can be worked around by following best-practice in unit test<br>
implementation. But people contributing to Squid have not been doing so<br>
consistently, and it is just a workaround.<br>
<br>
I do see somewhat more verbose output in the logs, and slightly less<br>
code to implement (no .h class). Which is a nice gain, but not what I<br>
would call "vastly superior".<br></blockquote><div><br></div><div>Right. A lot of value comes from the combination with gmock.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
> - porting memTest took me about one hour, mostly caused by us including<br>
> cppunit headers from squid.h (WUT? A PR is coming up to unentangle that)<br>
> <br>
<br>
Converting tests from one framework to another is not a problem. We just<br>
have nobody doing the legwork. Case in point being the old tests not<br>
even using cppunit.<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
The main problem(s) we have with testing of Squid is dev participation:<br>
<br>
 a) people are not writing tests to cover new code, and<br>
 b) people are not writing/updating tests to cover bug fixes, and<br>
 c) tests written are generally not following best practice design.<br>
<br>
IIRC Alex an I have different ideas about the ideal focus of testing;<br>
 * I prefer the micro-test approach to demonstrate a high quality proof<br>
of code reliability.<br>
 * Alex has stated a preference for high level black-box testing of<br>
behaviour vs design requirements.<br></blockquote><div><br></div><div>TBH I favour unit tests as well. But if we can have black box texting (and there are compliance testing frameworks to do that for us) that'd really increase the confidence in correctness over time. The two do not cancel each other, luckily. The former can do fast-feedback return, the latter can say "something is wrong" and then we can - if needed - bisect to point to a specific commit</div><div> </div></div><div><br></div>-- <br><div dir="ltr">    Francesco</div></div>