Sunday, January 31, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 2 topics

Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:25PM -0500

On 1/31/2016 9:00 AM, Jorgen Grahn wrote:
 
> There is no reason it should be manual in small or medium-sized
> projects ... building and running unit tests is one of the most easily
> automated tasks I can think of, provided you have half-decent tools.
 
It depends. I've seen a lot of small projects where the effort of
automating the test exceeds the manual effort required to do the testing.
 
> (Except if you're cross-compiling and this is the only thing you want
> to run on the host. But then doing it manually would be even harder.)
 
Maybe, maybe not. The tests would be the same, even when
cross-compiling. And, in fact, cross-compilation is even more likely to
be manually tested because the tools to do it automatically may not be
available on the target system, system constraints may not allow for the
tests to be run, or any of a number of other reasons.
 
> - The output when everything is fine doesn't fill your screen with
> information you won't read ("hey, did you know these 4711 tests
> all passed -- again?" followed by a complete list).
 
Tests should never be part of the build and should be performed by a
separate group, with the tests designed based on the documentation.
 
Programmers do a lot of building - you don't need to test with every
build. And the people writing the code should never be part of the test
environment - and aren't, in well-run projects. If the programmer
writes the tests, he/she will have a tendency to write the tests based
on the code they wrote (natural inclination). A separate group writing
the test will not do that.
 
> optional, but without all three bullets above, unit tests will never
> work well (IMO, of course).
 
> /Jorgen
 
Builds may be nightly - not necessarily. And by the time you get far
enough to do a nightly build, you should already have a lot of tests run.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Ian Collins <ian-news@hotmail.com>: Feb 01 12:34PM +1300

Jerry Stuckle wrote:
 
> The behavior of the real B's methods when used with A are the same in
> testing as in production. If the test requires one of B's methods to
> fail, then it will fail in both test and production.
 
So how do you get one of B's methods to throw an out of memory
exception? Or a <you name it> exception? Or return the result you
expect it to return after 100 calls?
 
--
Ian Collins
Ian Collins <ian-news@hotmail.com>: Feb 01 12:36PM +1300

Jerry Stuckle wrote:
 
>> Which would be pretty f'ing useless.
 
> Which is exactly why you wouldn't be using a mock of B. You'd use the
> real, *tested* B.
 
If a real B didn't behave as it's tests define it, it wouldn't be a
tested B, would it?
 
--
Ian Collins
Ian Collins <ian-news@hotmail.com>: Feb 01 12:37PM +1300

Jerry Stuckle wrote:
 
> You cannot properly test a class if behavior of dependent classes is
> mocked. You cannot ensure the dependent class's behavior will be the
> same when the real dependency is used.
 
If that is the case, your process is broken.
 
--
Ian Collins
Paavo Helde <myfirstname@osa.pri.ee>: Feb 01 01:38AM +0200

On 1.02.2016 1:13, Jerry Stuckle wrote:
 
> Alf, What I mean is that A is tested with the real B. If A depends on
> B, you can't ensure A works properly if you don't have a working B to
> test with.
 
You can never ensure that something works 100% properly. At best you can
hope to have a good enough test suite to catch most of the bugs. If a
bug surfaces in B, then there is not really much difference if it is the
unit test for A or for B which catches the problem. To have separate
unit tests for A and B is just to reduce the cyclomatic complexity in
writing the tests, there is no deep philosophical reason to separate them.
 
In TDD, if you develop a feature provided by A, you write a test for the
feature using A. The test first fails. Then you start to add code to
make the test pass. During that you see that one of the reasons why the
test fails is that B is not yet written. So you write B, adapt A to use
it and make the test pass. There is nothing in TDD that says you have to
figure out the class dependencies beforehand and start with lowest level
classes. TDD does not care about such implementation details. To ensure
better test coverage, you may later add a separate test for B, but this
would then be a pure unit test, not a TDD test (as it does not cover a
feature, but a technical detail).
 
Cheers
Paavo
Ian Collins <ian-news@hotmail.com>: Feb 01 12:42PM +1300

Jerry Stuckle wrote:
 
> Tests should never be part of the build and should be performed by a
> separate group, with the tests designed based on the documentation.
 
*Unit* test can (and should if your process requires test first coding)
be written and run by the developers. Integration, system and
acceptance (black box) testing may be performed by others if the team
include testers.
 
--
Ian Collins
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:42PM -0500

On 1/31/2016 6:34 PM, Ian Collins wrote:
 
> So how do you get one of B's methods to throw an out of memory
> exception? Or a <you name it> exception? Or return the result you
> expect it to return after 100 calls?
 
The same way you would in production - you create the scenario where the
exception would occur, and cause it. If it's impossible to test, then
it's impossible for the scenario to occur in production, anyway.
 
And if you expect a specific return after 100 calls, then you call it
100 times.
 
Anything that can happen in production can be tested for. Whether you
test for the extreme cases or not is up to you.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Ian Collins <ian-news@hotmail.com>: Feb 01 12:49PM +1300

Jerry Stuckle wrote:
 
> The same way you would in production - you create the scenario where the
> exception would occur, and cause it. If it's impossible to test, then
> it's impossible for the scenario to occur in production, anyway.
 
So you consume all of the memory on your test box, what then?
 
> And if you expect a specific return after 100 calls, then you call it
> 100 times.
 
..and if each call would fetch and parse a file from the internet?
 
> Anything that can happen in production can be tested for. Whether you
> test for the extreme cases or not is up to you.
 
Anything can be tested if you can afford the cost. Unit tests generally
can't afford to trash the host they are running on or create a DOS
attack on a remote server...
 
--
Ian Collins
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:50PM -0500

On 1/31/2016 6:38 PM, Paavo Helde wrote:
> unit test for A or for B which catches the problem. To have separate
> unit tests for A and B is just to reduce the cyclomatic complexity in
> writing the tests, there is no deep philosophical reason to separate them.
 
That's very true. But there is a very good reason for testing
separately - once you get rid of the bugs in the independent class, you
can be pretty sure any bugs which show up are in the dependent class.
If you don't test the independent class first, you have no idea where
the problem lies. And as you get more and more classes involved the
problem becomes more difficult.
 
> feature, but a technical detail).
 
> Cheers
> Paavo
 
The design will define the class dependencies. And every time you have
to rewrite A to adapt it to be, you are wasting programmer time, test
group time, and potentially inserting more bugs.
 
A proper design means the independent classes can be written first, and
the dependent ones later. This eliminates the need for programmers to
rewrite dependent code.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:51PM -0500

On 1/31/2016 6:36 PM, Ian Collins wrote:
>> real, *tested* B.
 
> If a real B didn't behave as it's tests define it, it wouldn't be a
> tested B, would it?
 
No. But a mock B wouldn't be used, because it doesn't necessarily
behave the same as the real B. If it did, it would be a real B.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:54PM -0500

On 1/31/2016 6:37 PM, Ian Collins wrote:
>> mocked. You cannot ensure the dependent class's behavior will be the
>> same when the real dependency is used.
 
> If that is the case, your process is broken.
 
If you think otherwise, then your process is broken.
 
Say you get the dependent class working with a mock independent class.
Now you create the independent class and test it. The dependent class
now fails tests because the mock independent class didn't perform the
proper actions.
 
So now you have to go back and rewrite the dependent class to work with
the real independent class instead of the mock one. You have now wasted
programmer and test group time by having to rewrite "working" code, and
introduced the possibility of even more bugs.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:55PM -0500

On 1/31/2016 6:42 PM, Ian Collins wrote:
> be written and run by the developers. Integration, system and
> acceptance (black box) testing may be performed by others if the team
> include testers.
 
Not a chance. Never in any of the major projects I've been involved in
have any tests been performed by the developers. That's where the bugs
come in, because the developer of a class may not have the same
understanding of what the class should do (which is more common than you
would think).
 
Developers will tend to write tests to the code. Test groups will write
tests to the documentation. Two entirely different things.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Ian Collins <ian-news@hotmail.com>: Feb 01 01:03PM +1300

Jerry Stuckle wrote:
> Now you create the independent class and test it. The dependent class
> now fails tests because the mock independent class didn't perform the
> proper actions.
 
So you didn't implement your mock correctly, go back and fix it.
 
> the real independent class instead of the mock one. You have now wasted
> programmer and test group time by having to rewrite "working" code, and
> introduced the possibility of even more bugs.
 
You have wasted time implementing a mock that didn't do what it said on
the tin.
 
--
Ian Collins
Ian Collins <ian-news@hotmail.com>: Feb 01 01:06PM +1300

Jerry Stuckle wrote:
>> include testers.
 
> Not a chance. Never in any of the major projects I've been involved in
> have any tests been performed by the developers.
 
There you go, on every project I've working on in the past decade and a
bit we have been using TDD, so all of the unit tests have been written
by the developers. All of the system and acceptance tests have been
written by our testers.
 
> would think).
 
> Developers will tend to write tests to the code. Test groups will write
> tests to the documentation. Two entirely different things.
 
Which is why we write the tests first.
 
--
Ian Collins
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 01 02:54AM +0100

On 2/1/2016 12:49 AM, Ian Collins wrote:
>> exception would occur, and cause it. If it's impossible to test, then
>> it's impossible for the scenario to occur in production, anyway.
 
> So you consume all of the memory on your test box, what then?
 
Well this was called "stress testing", some 15 years ago.
 
Checking… Yep, still.
https://en.wikipedia.org/wiki/Stress_testing_%28software%29
 
But yes, I agree, it would be impractical to ONLY wait for a rare but
important condition to occur, so as to observe it. Better to force it. I
guess that's the same as with an engine: the parts have to fit, but one
doesn't use actual fitness as primary testing, because that would be
impractical. So one measures. And only if the measurements say OK, does
one then assemble the thing and test the complete reality.
 
Yes?
 
 
Cheers,
 
- Alf
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 09:50PM -0500

On 1/31/2016 6:49 PM, Ian Collins wrote:
>> exception would occur, and cause it. If it's impossible to test, then
>> it's impossible for the scenario to occur in production, anyway.
 
> So you consume all of the memory on your test box, what then?
 
Then you test.
 
>> And if you expect a specific return after 100 calls, then you call it
>> 100 times.
 
> ..and if each call would fetch and parse a file from the internet?
 
Then it fetches and parses a file from the internet.
 
 
> Anything can be tested if you can afford the cost. Unit tests generally
> can't afford to trash the host they are running on or create a DOS
> attack on a remote server...
 
If a unit test trashes the host or creates a DOS attack on a remote
server, then the test is incorrect or the class fails. If it can happen
during testing, it can happen during production.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 09:52PM -0500

On 1/31/2016 7:03 PM, Ian Collins wrote:
>> now fails tests because the mock independent class didn't perform the
>> proper actions.
 
> So you didn't implement your mock correctly, go back and fix it.
 
And how do you know if it is implemented correctly if it isn't the full
class?
 
>> introduced the possibility of even more bugs.
 
> You have wasted time implementing a mock that didn't do what it said on
> the tin.
 
No, you have wasted time implementing a mock which doesn't perform the
same as the real unit.
 
Tell me - how is your mock class going to do the same work as the real
class if it isn't the real class? It's a lot more than just returning a
value from a method call.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 09:53PM -0500

On 1/31/2016 7:06 PM, Ian Collins wrote:
> bit we have been using TDD, so all of the unit tests have been written
> by the developers. All of the system and acceptance tests have been
> written by our testers.
 
Too bad. I'm sure you had a fair amount of bugs in the code.
 
 
>> Developers will tend to write tests to the code. Test groups will write
>> tests to the documentation. Two entirely different things.
 
> Which is why we write the tests first.
 
Which is exactly why developers do not write the tests.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:29PM -0500

On 1/31/2016 1:55 PM, 4ndre4 wrote:
> you can build with them. Remember that there are languages (such as
> Python, JavaScript, etc..) where there is no concept of "private
> method". Private methods are just a convention.
 
If the circuit works properly, you don't have to test each individual
electronic component.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:38PM -0500

On 1/31/2016 6:06 PM, Mr Flibble wrote:
> testable public methods. TDD is the enemy of both encapsulation in
> general and C++ in particular.
 
> /Flibble
 
Yes and no. Private methods are untestable directly, but they can be
tested through the public methods.
 
If the public methods don't call them, then the private methods are
unusable anyway. And even whether a private method exists or not is
immaterial; one could easily add or delete private methods and change
the public methods appropriately without changing the operation of the
class.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 11:45PM

On 31/01/2016 23:38, Jerry Stuckle wrote:
> immaterial; one could easily add or delete private methods and change
> the public methods appropriately without changing the operation of the
> class.
 
You obviously don't understand TDD then and its mantra of designing
upward from failing tests. Private methods are totally at odds with TDD.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Feb 01 12:51PM +1300

Mr Flibble wrote:
 
> You obviously don't understand TDD then and its mantra of designing
> upward from failing tests. Private methods are totally at odds with TDD.
 
Repeatedly burning your sausages doesn't make them good sausages.
 
--
Ian Collins
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 01 12:56AM

On 31/01/2016 23:51, Ian Collins wrote:
 
>> You obviously don't understand TDD then and its mantra of designing
>> upward from failing tests. Private methods are totally at odds with TDD.
 
> Repeatedly burning your sausages doesn't make them good sausages.
 
Except if you use TDD you don't end up with sausages you end up with
meatballs. TDD is anathema to best (SOLID) practices related to the
design of non-trivial software systems.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Feb 01 02:13PM +1300

Mr Flibble wrote:
 
> Except if you use TDD you don't end up with sausages you end up with
> meatballs. TDD is anathema to best (SOLID) practices related to the
> design of non-trivial software systems.
 
Restating the same empty nonsense won't make it any more correct.
 
There aren't any conflicts between TDD and SOLID practices. SOLID
practices help make TDD better. If I recall correctly, SOLID was
originally coined by Robert Martin (Uncle Bob) (possibly here:
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod). You may be
surprised to know that he is also a strong advocate of TDD:
https://blog.8thlight.com/uncle-bob/2014/05/02/ProfessionalismAndTDD.html
 
Go figure.
 
--
Ian Collins
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 09:48PM -0500

On 1/31/2016 6:45 PM, Mr Flibble wrote:
 
> You obviously don't understand TDD then and its mantra of designing
> upward from failing tests. Private methods are totally at odds with TDD.
 
> /Flibble
 
Oh, I understand it. And private methods have absolutely nothing to do
with TDD.
 
TDD deals with the external (public methods) interface of the class.
The internal (private methods) of the class are immaterial. In fact,
the private methods can change, be added or deleted without changing the
public interface - which is what TDD cares about.
 
How something is done - the implementation (which includes private
methods) is immaterial. What is material is the results.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

Digest for comp.lang.c++@googlegroups.com - 15 updates in 4 topics

Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 09:20PM

On 31/01/2016 18:45, 4ndre4 wrote:
> On 30/01/2016 23:11, Mr Flibble wrote:
 
>> If you eschew private methods and instead make everything public
 
> That's not what TDD is.
 
Sure it is.
 
/Flibble
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 09:23PM

On 31/01/2016 18:55, 4ndre4 wrote:
> you can build with them. Remember that there are languages (such as
> Python, JavaScript, etc..) where there is no concept of "private
> method". Private methods are just a convention.
 
You obviously don't understand class invariants. Any language that
doesn't offer private methods doesn't offer a way to easily enforce a
class invariant: no public method can break a class invariant by
definition. Such languages are at best toy and at worst harmful (just
like TDD).
 
Python and JavaScript are both toy.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Feb 01 10:51AM +1300

Mr Flibble wrote:
 
> Python and JavaScript are both toy.
 
Yeah right.
 
--
Ian Collins
Ian Collins <ian-news@hotmail.com>: Feb 01 11:03AM +1300

Mr Flibble wrote:
> wants lots of testable small (atomic) public methods to test but every
> public method you add actually REDUCES the encapsulation of a class
> whilst adding a private method does not sausages.
 
Er no, TDD doesn't want anything of the sort. Being a process, TDD
doesn't actually "want" anything at all except for tested, working code...
 
If you understood the process, you would know that there isn't any
conflict between TDD and encapsulation.
 
--
Ian Collins
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 11:06PM

On 31/01/2016 22:03, Ian Collins wrote:
> doesn't actually "want" anything at all except for tested, working code...
 
> If you understood the process, you would know that there isn't any
> conflict between TDD and encapsulation.
 
I do understand the process: private methods are untestable so should be
avoided in TDD land ergo encapsulation is increased when adding more
testable public methods. TDD is the enemy of both encapsulation in
general and C++ in particular.
 
/Flibble
Paavo Helde <myfirstname@osa.pri.ee>: Feb 01 01:17AM +0200

On 1.02.2016 1:06, Mr Flibble wrote:
> avoided in TDD land ergo encapsulation is increased when adding more
> testable public methods. TDD is the enemy of both encapsulation in
> general and C++ in particular.
 
Private methods are untestable only if they are never called by the
public methods. TDD tests the features and does not care how the class
provides these features.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 11:17PM

On 31/01/2016 23:17, Paavo Helde wrote:
 
> Private methods are untestable only if they are never called by the
> public methods. TDD tests the features and does not care how the class
> provides these features.
 
Meh.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 11:21PM

On 31/01/2016 23:17, Mr Flibble wrote:
>> public methods. TDD tests the features and does not care how the class
>> provides these features.
 
> Meh.
 
TDD wouldn't so bad if it wasn't ALSO an acronym for Test Driven DESIGN
which is of course total and absolute bollocks. Intelligence not failed
unit tests should driver design of non-trivial non-toy systems.
Ian Collins <ian-news@hotmail.com>: Feb 01 10:44AM +1300

Jorgen Grahn wrote:
>> inheritance. I will always mock an encapsulate class, with inheritance
> ^^^
> (I assume you meant "encapsulated" there.)
 
Yes.
 
 
> I've always figured bar is an implementation detail of Foo; that its
> state is part of Foo's state. So I ignore it when I'm testing Foo
> (assuming Bar itself doesn't do I/O or something).
 
There's the thing: most of the work I do these days is one or two steps
above the operating system interface, so there's a strong chance that
Bar will be doing I/O or something. The same degree of separation
applies to most embedded systems.
 
> arguing with coworkers about how to proceed with the testing? It's
> so frustrating when you only have your own opinions and prejudices
> as a starting point.
 
Doesn't anyone have colleagues any more? Sorry, I just hate the term
"coworkers"!
 
Back to the topic: what to reuse and what to mock? This is as much a
philosophical discussion as a technical one. Going too far in either
direction will result in either an incomprehensible mess or under
testing. Any project team will have to find their own happy place and
where that place lives between the two extremes will depend on the
domain and the personalities of the team members.
 
The last team I worked with were all detail focused (pedants if you
like) and working on a safety critical control system. This combination
naturally led to mocking everything except the class under test. Each
class had 5 files associated with it; the header and definition, the
test header and tests and the fifth being an (XML) interface description
used by the test framework to generate mocks.
 
> Bar to keep. You can also document what happens to Foo if Bar doesn't
> keep the contract, but I'm unsure if that has any value. I suspect
> you can list better arguments. You gave one below:
 
Another common case is where you want Bar to be in a particular state
when the method under test is called. If for example Bar implements a
state machine you may have to jump through hoops to get the real Bar
into the correct state.
 
> - programming errors (covered by Bar's unit tests)
> - incorrect usage (covered by Foo's unit tests)
> - memory allocation problems
 
Another case I often have is a function that filters a list of files,
say comparing entries from different filesystem snapshots. I want the
objects (or system call) that returns the file data to give me the data
(file type, size, timestamps) I need for the test.
 
Hope this helps,
 
--
Ian Collins
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:09PM -0500

On 1/31/2016 1:14 AM, Ian Collins wrote:
 
>>> A mock of B will behave exactly as the tests define it.
 
>> Which may or may not be the actual behavior of the class.
 
> Which would be pretty f'ing useless.
 
Which is exactly why you wouldn't be using a mock of B. You'd use the
real, *tested* B.
 
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:13PM -0500

On 1/31/2016 2:14 AM, Alf P. Steinbach wrote:
> called something else?
 
> Cheers, wondering,
 
> - Alf
 
Alf, What I mean is that A is tested with the real B. If A depends on
B, you can't ensure A works properly if you don't have a working B to
test with.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:15PM -0500

On 1/31/2016 2:42 AM, Ian Collins wrote:
> either have to pollute B with the code to synthesise a failure, or mock it.
 
> Yes at some point (typically in integration testing) you will be testing
> the real code in combination, but for unit testing A, you need to mock B.
 
The behavior of the real B's methods when used with A are the same in
testing as in production. If the test requires one of B's methods to
fail, then it will fail in both test and production. If it doesn't, you
have a problem - in both testing and production.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 06:17PM -0500

On 1/31/2016 1:42 PM, 4ndre4 wrote:
> random order. The unit tests for class A are supposed to test ONLY the
> behaviour for class A and not assume any dependency. If any dependency
> is needed, it should be mocked.
 
You cannot properly test a class if behavior of dependent classes is
mocked. You cannot ensure the dependent class's behavior will be the
same when the real dependency is used.
 
Tests are not in completely random order. Before testing a dependent
class, the class it is dependent on requires testing.
 
 
>> Please read the thread. We are talking about when there are multiple
>> classes in one file.
 
> My question stands.
 
Your question is meaningless because it's not part of what we are
discussing.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
woodbrian77@gmail.com: Jan 31 01:18PM -0800

On Sunday, January 31, 2016 at 2:40:21 PM UTC-6, Daniel wrote:
> > to debauchery. Instead, be filled with the Spirit." Ephesians 5:18
 
> "Drink no longer water, but use a little wine for thy stomach's sake and thine often infirmities."
 
> 1 Timothy 5:23
 
A little wine is maybe half of a single vodka.
Some here seem prone to excess.
"Öö Tiib" <ootiib@hot.ee>: Jan 31 08:53AM -0800

On Sunday, 31 January 2016 16:36:43 UTC+2, David Brown wrote:
> a startup code enabling the oscillator, waiting for it to stabilise,
> then sorting out your PLL's, dividers, clock enables, etc., for all the
> different parts of the system.
 
I meant that if more complexities are required to product's external
behavior then it is generally cheaper to do same on more powerful
and more general purpose architecture. There can be exceptions but
basics of those are common, can be reused and so can be even provided
as part of API from chip manufacturer. Everybody counts money so if
new features provide no benefits then they order and use older version.
 
> greatly reduce the effort. And then you get the boss and/or customer
> and/or company salesman saying "since you have such a powerful
> microcontroller, let's add /this/ feature to the software..." :-)
 
They know that more features cost more time and effort. If the idea
will likely fall short then I may have opportunity to improve on it that
we can do something similar that is more useful. Or if it is rare and
immediately useful idea then I have opportunity to make a better (more
likely winning on market) product. Or if it is bad idea then I have
opportunity to explain that our baby carriage does not perhaps benefit
from such expensive snowplough but we can try it out of course if we
have budget. On very rare case I have the misery to tell that it is
impossible (that they may interpret as me being lazy or stupid) and
so I am positive hero in eyes of those people.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

Paul <pepstein5@gmail.com>: Jan 31 01:11PM -0800

I am trying to present in C++ a set of algorithms for solving a problem. It is intended that the set of algorithms will expand. So far, I have five basic algorithms for solving the same problem. The end goal (so far) is to develop a simple user interface at the console so that the user can provide the parameters, together with a string indicating the name of the algorithm, and my code will provide the solution (and possibly the runtime).
 
Four of these algorithms are simple conceptually (although the maths is complicated). However, the fifth algorithm is much more involved because it has four or five features which can be absent or present so the fifth algorithm can really be thought of as 16 or 32 algorithms. (The vagueness is because I haven't decided which features to be settable by the user).
 
If I only had the first four to worry about, the design could be very simple.
I would have a pure abstract class as a base of all the algorithms. Finding the solution is a virtual function which depends on the algorithm selected by the user.
 
class Algorithm{
 
public:
Algorithm(some parameters);
virtual void findSolution() = 0;
}
 
class Method1 : public Algorithm
{
public:
Method1(some parameters) : Algorithm(some parameters)
{

}
void findSolution()
{
 
}
 
}
 
Methods 2, 3 and 4 could have the same design as Method 1.
 
But the complex method, method 5, makes it harder to design elegantly.
 
I could try
 
class Method5 : public Algorithm
{
bool flag1;
bool flag2;
...
public:
Method5 (some parameters, bool someFlag, bool someOtherFlag): Algorithm(some parameters), flag1(someFlag), flag2(someOtherFlag)
{

}
 
void findSolution()
{
if(flag1) doThis;
if(flag2) doThat;
////

}
}
 
However, now for Method 5, the approach no longer looks elegant.
 
Any ideas? I'm deliberately being vague about the precise nature of the problem because I want to decouple the maths side from the design side and I definitely don't want help on the maths side.
 
Many thanks,
 
Paul
Paul <pepstein5@gmail.com>: Jan 31 01:15PM -0800

On Sunday, January 31, 2016 at 9:12:05 PM UTC, Paul wrote:
> }
 
> However, now for Method 5, the approach no longer looks elegant.
 
> Any ideas? I'm deliberately being vague about the precise nature of the problem because I want to decouple the maths side from the design side and I definitely don't want help on the maths side.
 
Sorry, I missed the semicolons off the class definitions. And I need a virtual destructor too.
 
Paul
woodbrian77@gmail.com: Jan 31 12:16PM -0800

On Saturday, January 30, 2016 at 5:16:44 PM UTC-6, Mr Flibble wrote:
> Is having a triple vodka a thing?
 
> /Flibble
 
It's probably a siren song (deceptively alluring) thing.
 
 
Brian
Ebenezer Enterprises - "Do not get drunk on wine, which leads
to debauchery. Instead, be filled with the Spirit." Ephesians 5:18
 
http://webEbenezer.net
Daniel <danielaparker@gmail.com>: Jan 31 12:39PM -0800


> "Do not get drunk on wine, which leads
> to debauchery. Instead, be filled with the Spirit." Ephesians 5:18
 
"Drink no longer water, but use a little wine for thy stomach's sake and thine often infirmities."
 
1 Timothy 5:23
Paavo Helde <myfirstname@osa.pri.ee>: Jan 31 02:14AM +0200

On 31.01.2016 1:11, Mr Flibble wrote:
 
> If you don't think about or don't understand class invariants (which I
> suspect is the case for most TDD adherents) then your existing
> non-trivial designs really will be god-awful.
 
You have found another straw man to attack. Why should TDD prohibit
private methods or attempt to test them? The private methods are
declared private because they are not guaranteed to maintain class
invariant; declaring them private avoids other code calling them
accidentally (including any test code).
 
> TDD is the enemy of encapsulation. TDD really is a bad idea.
 
Non sequitur. Maybe you should stick to sausages?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 31 01:58AM +0100

On 1/31/2016 1:14 AM, Paavo Helde wrote:
> declared private because they are not guaranteed to maintain class
> invariant; declaring them private avoids other code calling them
> accidentally (including any test code).
 
Why should TDD not test private methods?
 
I understand from the "avoids … test code [calling them]" that you're
thinking of a case where somehow the private methods are inaccessible to
test code, but why should they be?
 
I'm just asking. I've not been into TDD very much. If it's really the
case that it's not applicable to private parts, or e.g. that there's no
idea of hierarchy and nesting and levels, then it seems that it's much
in need of modernization of tooling and/or methodology, like some
COBOL-like brute animal from the distant past?
 
 
Cheers,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Jan 30 06:06PM -0800

On Sunday, 31 January 2016 02:58:35 UTC+2, Alf P. Steinbach wrote:
 
> I understand from the "avoids ... test code [calling them]" that you're
> thinking of a case where somehow the private methods are inaccessible to
> test code, but why should they be?
 
It is generally more difficult if external software (including tests)
accesses the internal details and assumes those. So testing private methods
may make functionality or performance improving difficult, froze the
design and add unneeded internal paranoia bloat to class implementation.
 
> idea of hierarchy and nesting and levels, then it seems that it's much
> in need of modernization of tooling and/or methodology, like some
> COBOL-like brute animal from the distant past?
 
Code of unit tests is typically longer than code of class itself.
Sometimes order of magnitude longer. Now we maintain the class.
Tests fail. May be those are false positives or may be those are
not? May be the test assumed something unneeded? May be it was needed
but the writer of test was just lazy to achieve same situation from
public interface? If the tests do not cheapen the maintenance then
TDD is applied in harmful manner.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 31 03:42AM

On 31/01/2016 00:14, Paavo Helde wrote:
> accidentally (including any test code).
 
>> TDD is the enemy of encapsulation. TDD really is a bad idea.
 
> Non sequitur. Maybe you should stick to sausages?
 
It isn't a non-sequitur at all: do you understand encapsulation? TDD
wants lots of testable small (atomic) public methods to test but every
public method you add actually REDUCES the encapsulation of a class
whilst adding a private method does not sausages.
 
/Flibble
"Öö Tiib" <ootiib@hot.ee>: Jan 30 09:02PM -0800

On Sunday, 31 January 2016 05:42:12 UTC+2, Mr Flibble wrote:
> wants lots of testable small (atomic) public methods to test but every
> public method you add actually REDUCES the encapsulation of a class
> whilst adding a private method does not sausages.
 
That is not true at all. Typically TDD just tests that public interface
of a class does what it claims in interface specification.
So one using TDD wants to reduce public interface to minimum needed, not
to make private members public.
Ian Collins <ian-news@hotmail.com>: Jan 31 09:18PM +1300

Mr Flibble wrote:
> is impossible to maintain a class invariant except WITHIN a SINGLE
> public method which has the effect that some of your public methods MUST
> be unnecessarily large/complex.
 
TDD and using private methods are orthogonal.
 
Does your local butcher having a secret recipe for his sausages prevent
you from taste testing them?
 
--
Ian Collins
Paavo Helde <myfirstname@osa.pri.ee>: Jan 31 11:54AM +0200

On 31.01.2016 2:58, Alf P. Steinbach wrote:
 
> I understand from the "avoids … test code [calling them]" that you're
> thinking of a case where somehow the private methods are inaccessible to
> test code, but why should they be?
 
TDD means test-driven development. This means that when adding any
feature or fixing a bug one first writes a test which *uses* the needed
part of the software and first fails. Then code is added or modified so
that the test passes. The resulting code is refactored to become simpler
and more maintainable, while still passing the test. Finally the test is
added to the automatic test suite (if possible and feasible).
 
Note that in this description no methods or classes are mentioned, this
is all about *usage*. And usage happens only via public methods. What
happens inside the class is of no concern in TDD, as long as the tests
succeed.
 
Note that the concept of TDD is a bit orthogonal to unit testing. If the
TDD-tested feature is small enough, the TDD test may be added to the
unit test suite. If it is too large, it might be added to the
integration test suite. Or if it is used for development only (the last
'D' in TDD), then it is not added anywhere.
 
Private methods are more a topic for code reviews, unit testing and
mocked interfaces. There are probably projects where private methods are
considered units and tested accordingly. I have never done such things,
so have no experience, but I believe this could easily become an
overkill and counter-productive. For example, the refactoring step
present in the TDD cycle would become much harder.
 
Cheers
Paavo
4ndre4 <4ndre4@4ndre4.com.invalid>: Jan 31 06:45PM

On 30/01/2016 23:11, Mr Flibble wrote:
 
> If you eschew private methods and instead make everything public
 
That's not what TDD is.
 
--
4ndre4
"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense." (E. Dijkstra)
4ndre4 <4ndre4@4ndre4.com.invalid>: Jan 31 06:55PM

On 31/01/2016 03:42, Mr Flibble wrote:
 
[...]
> TDD
> wants lots of testable small (atomic) public methods to test but every
> public method you add actually REDUCES the encapsulation of a class
 
No, it doesn't. Sorry, but you haven't understood what TDD is. The fact
that you can test each individual electronic component available on the
market in isolation, does not mean that you are esposing any details
about the interaction between those components, on any electronic board
you can build with them. Remember that there are languages (such as
Python, JavaScript, etc..) where there is no concept of "private
method". Private methods are just a convention.
 
--
4ndre4
"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense." (E. Dijkstra)
Jerry Stuckle <jstucklex@attglobal.net>: Jan 30 09:40PM -0500

On 1/30/2016 6:09 PM, Ian Collins wrote:
>>> being able to control the behaviour of the B methods it is using.
 
>> But a mock of B may or may not behave the same.
 
> A mock of B will behave exactly as the tests define it.
 
Which may or may not be the actual behavior of the class.
 
>> the interaction between the two is part of the unit test of A.
 
> Consider the case where B isn't part of the project code but a third
> part library.
 
We're not talking about something that isn't part of the project.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Ian Collins <ian-news@hotmail.com>: Jan 31 07:14PM +1300

Jerry Stuckle wrote:
 
>>> But a mock of B may or may not behave the same.
 
>> A mock of B will behave exactly as the tests define it.
 
> Which may or may not be the actual behavior of the class.
 
Which would be pretty f'ing useless.
 
--
Ian Collins
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 31 08:14AM +0100

On 1/31/2016 7:14 AM, Ian Collins wrote:
 
>>> A mock of B will behave exactly as the tests define it.
 
>> Which may or may not be the actual behavior of the class.
 
> Which would be pretty f'ing useless.
 
No, it's necessary to test the pieces of each class working together, at
the level of unit testing. Traditional integration testing is at a
higher level. If this is not done then one risks that the tests for B do
not guarantee that B will behave the same as the mock-up of B for the A
testing, e.g. due to these tests not completely nailing down the B
behavior in all test cases and test sequences.
 
As a perhaps silly example, B might be a string class with encoding
checks. One of which is `is_ascii` (comes to mind because I've recently
posted about such a function). Perhaps tests for B fail to test
`is_ascii` for the edge case of empty string. Perhaps the mockup returns
`false` in this case, causing testing of A with mockup to succeed, while
the real B and design intention is return of `true`.
 
To discover that the B tests are incomplete, the real B needs to be
exercised in its intended environment. It's like, no plan survives
contact with the enemy. No set of tests survives contact with reality,
although it can survive contact with just mockups, which after all are
coded to just support the tests at hand, aren't they?
 
So in that respect Jerry Stuckle is right, as I see it.
 
But Jerry can possibly be wrong regarding his statement that "before you
can thoroughly test A you have to ensure B works". It depends very much
on what "thoroughly" means here. I suspect that Jerry's intended meaning
of "thoroughly" was and is that A is tested with the real B, while Ian's
meaning of "thoroughly" is that A is sort of thoroughly tested with a
mock-up of B, and that testing with real B is something else, maybe
called something else?
 
 
Cheers, wondering,
 
- Alf
Ian Collins <ian-news@hotmail.com>: Jan 31 08:42PM +1300

Alf P. Steinbach wrote:
> meaning of "thoroughly" is that A is sort of thoroughly tested with a
> mock-up of B, and that testing with real B is something else, maybe
> called something else?
 
You can't thoroughly test A with a real B because you can't control the
behaviour of the real B's methods. They will do what they naturally do,
but if your test requires one of B's methods to fail in some way you
either have to pollute B with the code to synthesise a failure, or mock it.
 
Yes at some point (typically in integration testing) you will be testing
the real code in combination, but for unit testing A, you need to mock B.
 
--
Ian Collins
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 31 08:11AM

On Sat, 2016-01-30, 4ndre4 wrote:
>> I agree -- for most cases. But sometimes (let's say 5%) some other
>> consideration makes following the convention suboptimal.
 
> Such as?
 
Actually, the considerations are always the same: readability,
maintainability and so on. I meant to say sometimes the 1:1 rule
doesn't optimize for that.
 
My example elsewhere in the thread was a set of small sibling classes
which are similar, but cannot be a template. But I'm sure there are
other examples.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 31 01:23PM

On Fri, 2016-01-29, Ian Collins wrote:
> for a unit.
 
> I think the case is clearer for encapsulation than it is for
> inheritance. I will always mock an encapsulate class, with inheritance
^^^
(I assume you meant "encapsulated" there.)
 
To me, that sounds, well, extreme. Where would you stop? If you
don't mock std::string, std::map etc, what's the difference between
them and one of your own classes (which you have tested elsewhere?)
 
class Foo { Bar bar; ... };
 
I've always figured bar is an implementation detail of Foo; that its
state is part of Foo's state. So I ignore it when I'm testing Foo
(assuming Bar itself doesn't do I/O or something).
 
Question: if these are two different ways of thinking about unit
tests for classes, do they have names? Can I refer to books, when
arguing with coworkers about how to proceed with the testing? It's
so frustrating when you only have your own opinions and prejudices
as a starting point.
 
(One entry point could perhaps be this and related entries:
http://c2.com/cgi/wiki?StandardDefinitionOfUnitTest
but there's no consensus there either.)
 
I've tried to think about benefits of mocking the encapsulated bar ...
one thing would be that you make it explicit what contract Foo expects
Bar to keep. You can also document what happens to Foo if Bar doesn't
keep the contract, but I'm unsure if that has any value. I suspect
you can list better arguments. You gave one below:
 
> Whether a base/encapsulated class class has been tested is
> irrelevant, you still need a mock object to simulate error
> conditions.
 
Hm ... yes, I can easily see memory allocation failures fitting in
there. But is there anything else, typically? It seems to me that a
class Bar which doesn't need mocking for /really/ obvious reasons like
it's doing I/O, will fail due to
- programming errors (covered by Bar's unit tests)
- incorrect usage (covered by Foo's unit tests)
- memory allocation problems
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 31 01:32PM

On Sat, 2016-01-30, 4ndre4 wrote:
>> them in the same file, once you finish with A, you need to go back and
>> test B again, because it's file has changed.
 
> What?!
 
Big deal; you run your unit tests constantly anyway.
(In my case; "make check" and the tests are built and executed, and
they print just three lines of "everything is fine" if all tests still
pass.)
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 31 02:00PM

On Sat, 2016-01-30, Jerry Stuckle wrote:
>> when anything changes in the repository. So there is no problem with
>> testing B again, this will be done uncountable times.
 
> Yes, if the testing is automated (and it is in most large projects),
 
There is no reason it should be manual in small or medium-sized
projects ... building and running unit tests is one of the most easily
automated tasks I can think of, provided you have half-decent tools.
 
(Except if you're cross-compiling and this is the only thing you want
to run on the host. But then doing it manually would be even harder.)
 
> that is true. But it still takes time and manpower to ensure the tests
> get run and to verify the results.
 
IMO, one major key to get unit tests to work in practice is:
- They're trivial to run as part of the build (e.g. everyone on the
project knows "make all test" will always run the correct set
of tests).
- They don't take a lot of extra time, compared to plain incremental
builds.
- The output when everything is fine doesn't fill your screen with
information you won't read ("hey, did you know these 4711 tests
all passed -- again?" followed by a complete list).
 
Other things (like reports and statistics from nightly builds) are
optional, but without all three bullets above, unit tests will never
work well (IMO, of course).
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
4ndre4 <4ndre4@4ndre4.com.invalid>: Jan 31 06:42PM

On 30/01/2016 22:28, Jerry Stuckle wrote:
 
[...]
> It does matter, and it's not at all unusual for a class to have other
> classes as members. You start out testing single classes. Then you can
> test classes which include the first class.
 
No, it doesn't matter in the least. Tests are normally executed in
random order. The unit tests for class A are supposed to test ONLY the
behaviour for class A and not assume any dependency. If any dependency
is needed, it should be mocked.
 
>> running the tests contained in SomethingTest.cpp?
 
> Please read the thread. We are talking about when there are multiple
> classes in one file.
 
My question stands.
 
--
4ndre4
"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense." (E. Dijkstra)
"Öö Tiib" <ootiib@hot.ee>: Jan 30 05:07PM -0800

On Saturday, 30 January 2016 20:36:17 UTC+2, David Brown wrote:
> the sort. It is believable that of the people who responded to that
> survey, that about 50% said that when they used some sort of wireless
> communication on a project, it included WiFi. But that's all.
 
It may be that there are more 8 bit MCUs sold than 10% but the overall
development effort share for such very constrained platforms can be very
likely only around 10% or less.
 
> embedded systems run Android, when in reality microcontrollers that are
> not powerful enough to run Android outsell ones that are by a factor of
> something like 10,000 to 1.
 
The survey can be skewed in one or other way, I do not also take it
as full truth. May be the Linuxes are not so common as it seems from that
page but even with next to nothing Micrium RTOS (µC/OS-II, III) we can do
multi-threading and dynamic resource management just fine if it is needed.
It is wise to keep things as simple and robust as possible (but not simpler
than possible).
 
> Cortex M) are very much on the increase. This makes it a lot more
> realistic to use "big system" features of C++ in a wider range of
> embedded systems.
 
It seems to be the trend. Embedded software is more complex and
"wise" so development cost affects price of end products more. Couple
cents for more powerful MCU can help to cut some tens of thousands
from development cost thanks to better tools and also allow bigger
ease of improving the product with software updates later.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 31 02:32AM +0100

On 1/31/2016 2:07 AM, Öö Tiib wrote:
 
> It is wise to keep things as simple and robust as possible (but not simpler
> than possible).
 
Oh, Einstein rears his ugly head again, LOLs. :)
 
Cheers, & happy weekend!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Jan 31 03:36PM +0100

On 31/01/16 02:07, Öö Tiib wrote:
 
> It may be that there are more 8 bit MCUs sold than 10% but the overall
> development effort share for such very constrained platforms can be very
> likely only around 10% or less.
 
That's another matter, of course. All sorts of statistics can be
produced to say all sorts of things. My main point is that it nonsense
to think that 50% of MCU's are used with WiFi, no matter how you count
it (units shipped, developers using them, number of projects, dollars,
whatever).
 
I believe we agree on the basic points here anyway.
 
> cents for more powerful MCU can help to cut some tens of thousands
> from development cost thanks to better tools and also allow bigger
> ease of improving the product with software updates later.
 
Certainly that's the trend - though I am not sure that it cuts
development costs so much in practice. The most powerful micros give
you new opportunities (such as the freedom to use C++), but also make
some things more complex. When you use an AVR with a crystal reference,
the chip starts up running at the speed you picked with the choice of
crystal. When you use an M4 with a crystal reference, you usually have
a startup code enabling the oscillator, waiting for it to stabilise,
then sorting out your PLL's, dividers, clock enables, etc., for all the
different parts of the system. The ability to use 32-bit integers and
basic maths without worrying about the time and space costs does not
greatly reduce the effort. And then you get the boss and/or customer
and/or company salesman saying "since you have such a powerful
microcontroller, let's add /this/ feature to the software..." :-)
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.