Showing posts with label testing. Show all posts
Showing posts with label testing. Show all posts

Friday, 23 June 2017

Development : My Top Three Testing Tips

I've said before, and I'll say again, I'm not a fan of Test Driven Development, tests and test frameworks have their place, but they should not; in my opinion; be the driving force behind a projects development stream - even if it does give managers above the dev team a warm fuzzy sense of security, or if it allows blame to be appropriated later, you're a team, work as a team and use tests on a per-developer basis as a tool not as a business rule.

*cough* I do go off topic at the start of posts don't I... *heerrhum*, right... Top Three Automated Testing Tips... From my years of experience...


1. Do not test items which are tested by masses of other developers... I'm talking about when you're using a frame work of library, ensure you are using it correctly certainly, do this at training or with your coding standard, but then do not labour the point by re-testing... Lets take a good example of this, the C++ Standard Library.

The Standard Library contains many collection classes, these classes have iterators within, lets look at a vector:

#include <vector>

std::vector<int> g_SomeNumbers { 1, 3, 5, 7, 9 };

We could iterate over the collection and output it thus:

int g_Sum(0);
for (int i (0); i < g_SomeNumbers.size(); ++i)
{
    g_Sum += g_SomeNumbers[i];
}

However, this is not leveraging the STL properly, you are introducing the need to test the start poing "int i(0);" the end condition "i < g_SomeNumbers.size();" and the iterator "++i", three tests, slowing your system down and complicating your code base.

int g_Sum(0);
-- TEST SUM START
-- TEST i COUNT START
-- TEST RANGE CONDITION LIMIT
for (int i (0); i < g_SomeNumbers.size(); ++i)
{
    -- TEST ITERATION
    g_Sum += g_SomeNumbers[i];
    -- TEST SUM CALCULATION - THE ACTUAL WORK DONE
}
-- REPORT TESTS

Using the iterator, we leverage all the testing of the STL, we remove the need to range test the count variable, we remove the need to test the condition and leave only the step as a test to carry out...

int g_Sum(0);
for (auto i(g_SomeNumbers.cbegin()); i != g_SomeNumbers.cend(); ++i)
{
    g_Sum += (*i);
}

Our code looks a little more alien to oldé timé programmers however, it's far more robust and requires less tests simply because we can trust the STL implementation, if we could not thousands, hundreds of thousand of developers with billions of other lines of code would have noticed the issue, our trivial tests show nothing of gain, so long as we've written the code to a standard which uses the interface correctly...

int g_Sum(0);
-- TEST SUM START
for (auto i(g_SomeNumbers.cbegin()); i != g_SomeNumbers.cend(); ++i)
{
   -- TEST ITERATION
    g_Sum += (*i);
   -- TEST SUM CALCULATION - THE ACTUAL WORK DONE
}
-- REPORT TESTS


2. Do now allow values which have been tested to change unexpectedly... I'm of course talking about "const", which I have covered before on these pages, but constness in programming is key.  The C family of languages allow constness at the variable level, you may notice in the previous point I used a const iterator (with cbegin and cend) as I do not want the loop to change the values within the vector... Constness removes, utterly, the need to perform any tests upon the integrity of your data.

If it's constant, if the access to it is constant, you do not need to test for mutations of the values.

Your coding standard, automated scripts upon source control submissions, and peer review are your key allies in maintaining this discipline, however it's roots stretch back into the system design and anlysis stages of the project, to before code was cut, when you were discussing and layout out the development pathway, you should identify your data consider it constant, lock it down, and only write code allowing access to mutable references of it as and when necessary.

Removing the need to retest mutable calls, removing the need to log when a mutable value is called because you trust the code is key.

In languages, such as python, which do not directly offer constness, you have to build it in, one convention is to declare members of classes with underscores to intimate they are members, I still prefer my "m_" for members and "c_" for constants, therefore my post-repository submit hooks run scripts which check for assigning to, or manipulation of "c_" variables.  Very useful, but identified by the coding standard, enforced by peep review, and therefore removed from the burden of the test phase.


3. Remove foreign code from your base... I'm referring to code in another language, any scripting, any SQL for instance, anything which is not the pure language you are working within should be removed from the inline code.

This may mean a stored procedure to store the physical SQL, rather than inline queries throughout your code, it maybe the shifting of javascript functions to a separate file and their being imported within the header of an HTML page.

But it also includes the words we ourselves use, be that error messages, internationalisation, everything except code comments which is in whatever language you use (English, French etc etc) should be abstracted away and out of your code.

Your ways of working, coding standards, analysis and design have to take this into account, constness plays it's part as well, as does mutability, where ever you move this language to, and whatever form it takes test it a head of time, and then redact that test from your system level tests, trust you did it right based on the abstraction you've performed.  Then avoid burdening your system throughout the remaining development cycle.

One could expand this to say "any in-house libraries you utilise, trust their testing" just as I stated with the STL in my first point, however, I am not talking about code, I am talking about things which are not code, which are uniquely humanly interpretable.

The advantage of removing them and pre-testing the access to them is that you retain one location at which you have an interlink, one place at which a value appears, one place where they all reside and so you leverage easily converting your programs language, you leverage easily correcting a spelling mistake, and all without needing to change your system code; perhaps without needing to even re-release or re-build the software itself (depending on how you link to the lingual elements)

Ultimately reducing the amount of testing required.

Wednesday, 20 July 2016

Gaming/Software Engineering : The State of Testing

I'm going to have to be a crusty old bloke for this one... But bare with me... When I was a lad you had a 3.5" disk delivering your game to the customer (I was that customer), when I was a kid you had that audio data cassette delivering your game... If you had a bug, you had a problem, because that game never worked for your customers.

This trend, this ethos that you had to test your stuff was necessary, critical even, and I think rightly it was a corner stone of my computing education.

Yes, when I started to program I would just throw a few lines of code together, but as soon as that became a formal skill, with formal training, I had to start to test my code, I had to start to make sure things worked and not just in the normal everyday ways, but obscure, off spec and all possible ways.

This has become a core skill, and I'm sure I annoy some of my younger colleagues when they have a problem; which they have done their due diligence on but they have no idea what their bug or problem is; and I walk along listen, look at it, and come up with the answer, and if not the answer at least a plausible set of leads for investigation.

Its understandable, after all these years, I do know what I'm doing, I have dealt with systems, and hardware, and people and things going wrong so many times, in so many ways sometimes you can just feel what's going to be wrong.

The trouble today I find is it is very hard to express this skill onto others, you can't just impart all your experience to them, and when you sit and write down some of the more off the wall, but important examples, people don't believe you.  Or they believe that you're exaggerated, or they simply don't want to listen.

And so I'm seeing a generation of developers whom don't look to test, I've seen them release, to customers, some horrible, terrible code, which was buggy, broken and even tantamount to criminal.

What do these developers expect to happen?... Well, unfortunately, the half dozen or so I have been dealing with, their 20-24 age group mantra, seems to be "it's Alpha" or "it's Beta" and then the death nell for their credibility from me is "the customers will find it".

The customers will find it... Not the volunteer testers... Not the testing department... Not themselves... the Customer, someone whom has paid for, or bought into, their ideas.

Too many times, too often, and too readily, developers are passing the testing phase from themselves to others.

This was a good thing, about five or ten years ago when this trend began, programs and systems went through some form of testing and then went to open testing, to volunteers, to start that feedback cycle.  But all too often today, it's written and thrown back out there.

I hate it, I really hate it, I really wish some of those developers could stop, look at their projects; and they're good, if not potentially great projects; and then fix their shit.

Friday, 5 February 2016

DCC Train Test Bed

I've spent some time this evening actually getting around to setting up a length of 00 Gauge railway track, in order to test my DCC base station and sniffer builds.

I've lots of electronics lying around and to be honest I need to knuckle down and play about with them more.


You can see I have a reference DCC station here, a Gaugemaster unit, I'd much prefer to have the actual ESU Ecos system on the real-layout, but Ken wouldn't let me bring it home... not least as it'd leave him with nothing to play with.

Anyway, you can see this is actually longer than my desks, so it goes way off into the ether, and I've propped the left end up (just to stop it sagging under it's own weight) with a cardboard tube I had lying around.

Then, in the center above the mini screw drivers you can see the pile of Arduino Uno boards I have, and then the mess of electronics in various re-purposed glass jars.

And my quality £3 volt meter just poking into view... Hey, hey, it's not a Fluke, but it does the job for now.

Wednesday, 30 January 2013

Tester Communication


Understanding the difference between a fault, and a feature, is important in software development.  For most serious programmers we can joke that a bug is an unintended feature or even more honestly a cock up.

But sometimes you have to really listen to the person reporting a fault, to empathise with them and to get into their shoes.

This relating to your customer is a real big theme at the moment, as we're on deadline for today (in fact Friday, but we're saying today to put that extra spring in our steps) to deliver a really big system for a show, so now only has it got to work flawlessly, but it has to be in a saleable distributable situation.

For this we have a league of testers working live on the system, so as fixes feed out to the lead tester he does a generic test and all the automated stuff, and then he hands the builds over to different people to try to break them.

And today, I had a major call that one of my systems was failing soak, it was "leaking memory" was the report.

I have since last night spent perhaps 8 hours trawling the code, doing builds and tests and checking, there's nothing being wasted, nothing being unallocated, nothing being allocated and then abandoned, it is in the technical sense not leaking memory.

So, I've puzzled over this, and in the end gone down to talk to the testers, I've asked them to show me a machine, they happen to have one which had been on all night and it had a huge amount of memory being taken by "your application".

It was the logger, the log of activity, the debug log which should be turned off was still on, accruing string after string after string of text, nearly 500 megabytes of it over night in fact.  Double click to clear the log, or better yet turn it off, and no "memory leak".

What had happened was this user had heard of "memory leaks", and knew that the phrase was associated with memory being allocated that they could not account for.  But they'd not thought about what the system as actually doing, they had reported a "memory leak" and caused other semi-conscious technical users to panic, I myself had panicked.

Let this be a lesson learned.