CPPUnit how do I write a test? - c++

Okay I basically want to get the ball rolling and write some CPPUnit tests but I have no idea how to go about it. Here I have some code that basically gets a pointer to the Menu Button for the associated button group and position arguments, how would I go about creating a test for this?
CMenuButton* CMenuContainer::GetButton(const enumButtonGroup argGroup, const int32_t argPosition)
{
CMenuButton* pButton = NULL;
if (argGroup < MAX_GROUP_BUTTONS)
{
pButton = m_ButtonGroupList[argGroup].GetButton(argPosition);
}
return pButton;
In reply to #Fabio Ceconello, would it be possible to set some tests for some code like this?
unsigned long CCRC32::Reflect(unsigned long ulReflect, const char cChar)
{
unsigned long ulValue = 0;
// Swap bit 0 for bit 7, bit 1 For bit 6, etc....
for(int iPos = 1; iPos < (cChar + 1); iPos++)
{
if(ulReflect & 1)
{
ulValue |= (1 << (cChar - iPos));
}
ulReflect >>= 1;
}
return ulValue;
}

CppUnit isn't well suited for creating automated tests for user interface. It's more for processing-only units. For instance, let's say you created a replacement for std::vector and want to make sure it behaves like the original one, you could write tests that add elements to both your and the standard implementation, then do some more handling (removing, changing elements, etc.) and after each step check if the two have a consistent result.
For UI I'm not aware of good open source/free tools, but one good commercial tool is TestComplete from Smart Bear, among others.
For the second example you gave, the first thing is to define a validity check for the Reflect() method. You can, for instance, calculate the result of some values by hand to check if the returned value for each of them is what was expected. Or you could use an inverse function that's known to be fully working.
Assuming the first option, you could write the test like this:
class CRC32Test : public CppUnit::TestCase
{
public:
CRC32Test( std::string name ) : CppUnit::TestCase( name ) {}
void runTest()
{
struct Sample {unsigned long ulReflect; char cChar; unsigned long result};
static Sample samples[] =
{
// Put here the pre-calculated values
};
int count = sizeof(samples) / sizeof(Sample);
for (int i = 0; i < count; ++i)
CPPUNIT_ASSERT(subject.Reflect(samples[i].ulReflect, samples[i].cChar) == samples[i].result);
}
private:
CRC32 subject;
};
int main(void)
{
CppUnit::TextUi::TestRunner runner;
runner.addTest(new CppUnit::TestCaller<CRC32Test>("test CRC32", &CRC32::runTest));
runner.run();
}

Related

Creating ArrayBuilders in a Loop

Is there any way to create a dynamic container of arrow::ArrayBuilder objects? Here is an example
int main(int argc, char** argv) {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
tmp.Reserve(rowCount);
builders.push_back(tmp);
}
return 0;
}
This yields error: variable ‘arrow::Int64Builder tmp’ has initializer but incomplete type
I am ideally trying to build a collection that will hold various builders and construct a table from row-wise data I am receiving. My guess is that this isn't the intended use for builders, but I couldn't find anything definitive in the Arrow documentation
What do your includes look like? That error message seems to suggest you are not including the right files. The full definition for arrow:Int64Builder is in arrow/array/builder_primitive.h but you can usually just include arrow/api.h to get everything.
The following compiles for me:
#include <iostream>
#include <arrow/api.h>
arrow::Status Main() {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
ARROW_RETURN_NOT_OK(tmp.Reserve(rowCount));
builders.push_back(std::move(tmp));
}
return arrow::Status::OK();
}
int main() {
auto status = Main();
if (!status.ok()) {
std::cerr << "Err: " << status << std::endl;
return 1;
}
return 0;
}
One small change to your example is that builders don't have a copy constructor / can't be copied. So I had to std::move it into the vector.
Also, if you want a single collection with many different types of builders then you probably want std::vector<std::unique_ptr<arrow::ArrayBuilder>> and you'll need to construct your builders on the heap.
One challenge you may run into is the fact that the builders all have different signatures for the Append method (e.g. the Int64Builder has Append(long) but the StringBuilder has Append(arrow::util::string_view)). As a result arrow::ArrayBuilder doesn't really have any Append methods (there are a few which take scalars, if you happen to already have your data as an Arrow C++ scalar). However, you can probably overcome this by casting to the appropriate type when you need to append.
Update:
If you really want to avoid casting and you know the schema ahead of time you could maybe do something along the lines of...
std::vector<std::function<arrow::Status(const Row&)>> append_funcs;
std::vector<std::shared_ptr<arrow::ArrayBuilder>> builders;
for (std::size_t i = 0; i < schema.fields().size(); i++) {
const auto& field = schema.fields()[i];
if (isInt32(field)) {
auto int_builder = std::make_shared<Int32Builder>();
append_funcs.push_back([int_builder] (const Row& row) ({
int val = row.GetCell<int>(i);
return int_builder->Append(val);
});
builders.push_back(std::move(int_builder));
} else if {
// Other types go here
}
}
// Later
for (const auto& row : rows) {
for (const auto& append_func : append_funcs) {
ARROW_RETURN_NOT_OK(append_func(row));
}
}
Note: I made up Row because I have no idea what format your data is in originally. Also I made up isInt32 because I don't recall how to check that off the top of my head.
This uses shared_ptr instead of unique_ptr because you need two copies, one in the capture of the lambda and the other in the builders array.

Inserting an object from a derived class into another instance of said object (using the vector.insert function) C++

I am currently working through code which has a Road class. This has a vector of lanes and includes a lane class. The lane class has a vector of vehicles and each vehicle has its derived classes (Car, Motorcycle, Lorry).
I would like a vehicle to be able to assess whether it can move into another lane, i.e. be inserted into another lane's vector of vehicles, safely (a car requires some safe distance, so I have already implemented how a vehicle knows if it is clear to switch lanes).
void Road::Simulate(double time)
{
for (unsigned int iLane = 0; iLane < getNLanes()-1; iLane++)
{
for (unsigned int iV = 0; iV < getCurrentLane(iLane)->getNVehiclesinLane(); iV++)
{
std::cout<< " AllowedOvertake TEST "<< getCurrentLane(iLane+1)->allowedOvertake(getCurrentLane(iLane)->getCurrentVehicle(iV)->getPosition(), getCurrentLane(iLane)->getCurrentVehicle(iV)->getMinDistance())<<std::endl;
getCurrentLane(iLane+1)->setCanOvertake(allowedOvertake(getCurrentLane(iLane)->getCurrentVehicle(iV)->getPosition(), getCurrentLane(iLane)->getCurrentVehicle(iV)->getMinDistance()));
if (getCurrentLane(iLane+1)->getCanOvertake() == true)
{
getCurrentLane(iLane+1)->insertVehicle(getCurrentLane(iLane)->getCurrentVehicle(iV), 0);
delete getCurrentLane(iLane)->getCurrentVehicle(iV);
}
}
}
for (unsigned int iLane = 0; iLane < getNLanes(); iLane++)
{
getCurrentLane(iLane)->Simulate(time);
}
}
I loop over all the present lanes, except the last one as any vehicle in this lane cannot overtake. After looping over the vehicles contained in each lane, I have a function which returns a Boolean which confirms whether an overtake scenario can be executed. This is done in allowedOvertake(). If this returns true, I implement an insert function.
My issue/question: How can I make this ideology work, and whether it is sensible to have these setCanOvertake() and getCanOvertake() functions.
One possible solution could be to just pushback a new vehicle into the intended lane, but with the appropriate positions, velocities etc. However, I am not sure how to ensure that the vehicle being entered has the same type (Car, Lorry...) too.
Currently, I do not get any build errors if I exclude the insertVehicle() function, and I have vehicle motion being drawn using QPainter. However, with the insertVehicle() function, I do not get any build errors but I do get a crash once I run the project.
Any help would be appreciated, and apologies for any coding errors (I'm a keen, but very inexperienced C++ user).
For reference, I have the above functions' definitions as follows
bool Lane::allowedOvertake(double pos, double mindist)
{
for (unsigned int iV = 0; iV < getNVehiclesinLane() - 1; iV++)
{
if ((fVehicles[iV]->getPosition() > pos - mindist)// If inside rear safety distance.
|| fVehicles[iV]->getPosition() < pos + mindist)// If inside front safety distance.
{}//continue
else {return false;}
}
return true;
}
//IN Lane.h
bool getCanOvertake() const{return FREE_LANE_OVERTAKE;}
//IN Lane.h
void setCanOvertake(bool overtake = true){FREE_LANE_OVERTAKE = overtake;}
Apologies, I was under the impression I had referenced my insertVehicle() function definition.
void Lane::insertVehicle(Vehicle*v, int ielement) {
Vehicle* vins = new Vehicle(v->getPosition(), v->getVelocity(), v->getAcceleration());
for (unsigned int iDist = 0; iDist < fVehicles.size()+1; iDist++){fVehicles.insert(fVehicles.begin() + (ielement+1), vins);}
}

Unit testing: Am I doing right when using another method in unit testing a method?

To my best knowledge, unit testing should be done on each public API separately. But, I have been experiencing with a situation in which I have not found out a clear way to unit test each API independently as shown in the following example:
class MyStorage {
private:
std::vector<int> int_vec_;
public:
bool insert_int(int value);
int get_value_at(int idx);
}
I used GooogleTest framework and wrote unit tests as follows:
int int_tenth(int x) { return x * 10; }
TEST_F(MyStorageTest, insert_int) {
for(int i = 0; i < 10; i++) {
int value = int_tenth(i);
bool ret = my_storage.insert_int(value);
ASSERT_TRUE(ret);
}
}
TEST_F(MyStorageTest, get_value_at) {
for(int i = 0; i < 10; i++) {
int value = int_tenth(i);
my_storage.insert_int(value);
}
for(int i = 0; i < 10; i++) {
int expected_value = int_tenth(i);
int value = my_storage.get_value_at(i);
ASSERT_EQ(expected_value, value);
}
}
Am I doing right? If not, how can I make unit tests for this example?
I think this looks "okay". Your test case is exercising both APIs - and yes, you need to use the insert method in order to test the get method.
What is missing: corner cases, especially for get. Like: having test cases for negative indixes. Or invalid indexes. Such tests should result in certain errors - and you might want to make sure that the expected errors (for example exceptions) show up.
Beyond that you might want to look into libraries that are based on the QickCheck idea (where the test framework runs random tests to find violations of properties that you specify for your production code).

return a char function with random options and local variables

I have created a unit test harness to test my program. I wanted it to be able to randomly test each run but I'm not sure how to go about doing this. Here is what I was think but I get stuck on what to do next, any guidance would be much appreciated.
int main (void)
{
int testNumber = 1; //for testing
char carName[] = "";
double carCost = 0;
carName = carChosen (testNumber);
carCost = assessCost (carName); //assessCost takes in the car name and checks what cost of the car will be (error checking so only certain cars can be chosen)
return 0;
}
"testNumber" would normally be seeded with time to create different number's from 1 - 15, but in this situation it's going to be "1" for testing.
This is next bit that I'm having trouble with. Within this function there would be 15 diffrent car options and it will return one depending on the randomly created number.
char carChosen (int randNum)
{
char carOne[] = "Honda";
char carTwo[] = "Ford";
if (randNum == 1)
{
return carOne; //local variables, not going to work...
}
else if (randNum == 2)
{
return carTwo; // Again, these return's are here to better represent what I'm trying to create but failing to do so..
}
}
I understand you cannot return local variables, what can I do instead?
This
void carChosen (int randNum, char * out)
{
char carOne[] = "Honda";
char carTwo[] = "Ford";
if (randNum == 1)
{
strcpy(out, carOne);
}
else if (randNum == 2)
{
strcpy(out, carTwo);
} //.. handle other cases
}
Call like
char carName[MAX_LEN];
carChosen (testNumber, carName);
Also maybe you are better of using switch instead of nested if..else if you have many conditions to test.
I thought it was C looking at the code, if you use C++, you can just return std::string objects from your function without any issues.
As others have pointed out, your code looks like C code. If you want to use C++, then read up on std::string and use that.
If you want to continue with your approach (which is very much a C-like approach), then you'll need to better understand how C strings work. Namely, how they are stored in memory and how a char is different from a char * is different from a char array[].
Putting most of that aside for now, my first guess based upon your example code is that you won't actually be modifying the contents of the string. You just want the string for its contents, but you won't be changing them. If this is accurate than you can just use regular char * variable to hold a pointer to a char string. You only need one copy of the string hanging around, so you can pass around a pointer to that one copy and everyone can read from that pointer. A quick way to do this is to just use the string literal directly.
const char* carChosen (int randNum)
{
if (randNum == 1)
{
return "Honda";
}
else if (randNum == 2)
{
return "Ford";
}
else
{
return "Audi";
}
}
Note that we are returning a const char *. The const is just indicating that we will not be modifying the string that is pointed to. We definitely do not want to do that because it points to a string literal (which you are not allowed to modify). Once you have the const char * returned by carChosen, you can pass that along to other functions, e.g. assessCost.

Assigning Unique ID's to each instance of a class

I am importing items from an XML file. Each XML element (FoodItem, Person, Order, CoffeeRun) is a class & each of these elements will have a unique ID(unique to that class).
<person>
<id>0</id>
<name>...</name>
</person>
<FoodItem>
<id>0</id>
<name>Coffee</name>
</FoodItem>
I am trying to develop a sub class DatabaseItem, that ensures that no 2 objects of a class have the same ID. Can you assist me, by helping me develop an efficient algorithm that makes sure no object will have the same ID as another?
My 2 approaches seem a little inefficient to me:
Use a static class vector that contains all the USED ids so far. When a new DatabaseID( int requestedID ) object is created I check whether the ID is available by going over all the used values in the vector to check the ID is not already there, I think thats Big-O'n speed?
Use a static class bool vector where each element of the vector corresponds to an id (so vector[1] will correspond to the object with ID 1). I check if an ID is already taken by seeing if that element in the vector is true if ( v[nID] == true ) { // this ID is already taken }. This seems inefficient because it means my vector will take a lot of memeory right?
I am not familiar with using maps in C++ but maybe I should use one here?
Any advice on an efficient algorithm would be really helpful:
class DatabaseItem
{
public:
static unsigned int instanceCount;
DatabaseItem()
{
// Assign next available ID
}
DatabaseItem( unsigned int nID )
{
// Check that that id is not already taken
// if id is taken, look for next available id &
// give the item that id
}
private:
unsigned int uniqueID;
};
// My solution: Do you have any better ideas that ensure no objects jave the same ID?
// This seems REALLY inefficient...
class DatabaseItem
{
public:
static unsigned int instanceCount;
static vector <unsigned int> usedIDs;
DatabaseItem()
{
DatabaseItem::instanceCount++;
uniqueID = instanceCount;
usedIDs.add( instanceCount );
}
DatabaseItem( unsigned int nID )
{
if ( isIDFree( nID ) )
{
uniqueID = nID;
}
else uniqueID = nextAvailableID();
DatabaseItem::instanceCount++;
}
bool isIDFree( unsigned int nID )
{
// This is pretty slow to check EVERY element
for (int i=0; i<usedIDs.size(); i++)
{
if (usedIDs[i] == nID)
{
return false;
}
}
return true;
}
unsigned int nextAvailableID()
{
while ( true )
{
unsigned int ID = 0;
if ( isIDFree( ID ) )
{
return ID;
}
else ID++;
}
}
private:
unsigned int uniqueID;
};
// Alternate that uses boolean vector to track which ids are occupied
// This means I take 30000 boolean memory when I may not need all that
class DatabaseItem
{
public:
static unsigned int instanceCount;
static const unsigned int MAX_INSTANCES = 30000;
static vector <bool> idVector;
// Is this how I initialise a static class vector...? (note this code will be outside the class definition)
// vector <bool> DatabaseItem::idVector( MAX_INSTANCES, false );
DatabaseItem()
{
uniqueID = nextAvailableID();
idVector[uniqueID] = true;
}
DatabaseItem( unsigned int nID )
{
if ( nID >= MAX_INSTANCES )
{
// not sure how I shd handle this case?
}
if ( idVector[nID] == false )
{
uniqueID = nID;
idVector[nID] = true;
}
else
{
uniqueID = nextAvailableID();
idVector[uniqueID] = true;
}
instanceCount++;
}
unsigned int nextAvailableID()
{
for (int i=0; i<idVector.size(); i++)
{
if ( !idVector[i] )
{
return i;
}
}
return -1;
}
bool isIDFree( unsigned int nID )
{
// Note I cannot do this: Because I am using Mosync API & it doesn't support any C++ exceptions'
// I declare idVector with no size! so not idVector( 30000, false)... just idVector;
// then I allow an exception to occur to check if an id is taken
try
{
return idVector[nID];
}
catch (...)
{
return true;
}
}
private:
unsigned int uniqueID;
};
A vector<bool> is implemented with one bit per bool, so it's not wasting as much space as you assume.
A set<unsigned int> is the easy solution to this. A vector<bool> is faster. Both could use a bit of memory. Depending on your usage patterns, there's a few other solutions:
An unsigned int all_taken_upto_this; combined with a set<int> covering all the oddball ID's that are higher than all_taken_upto_this - remove from set and increase the counter when you can.
A map<unsigned int, unsigned int> which is logically treated as begin,end of either taken or free sequences. This'll take a little fiddling to implement correctly (merging consecutive map elements when you add the last ID in between two elements e.g.)
You could probably use a premade "sparse bitset" type data structure - I don't know any implementations OTOH.
Depending on the number of elements and a couple other issues, you might consider actually storing them (or at least pointers to them) in a map. That would be rather simple to implement, but will take some space. On the other hand, it will provide you with fast lookup by id which might be a clear advantage if there are cross references in the XML. The map (assuming pointers) would look like:
std::map<int, std::shared_ptr<Object> > id_map;
std::shared_ptr<Object> p( new Object( xml ) );
if ( !id_map.insert( std::make_pair( p->id, p ) ).second ) {
// failed to insert, the element is a duplicate!!!
}
If you are not locked into using an integer you may look into GUIDs (Global Unique IDs). Depending on which platform you are using you can generally find a couple of utility functions to dynamically generate a GUID. If using Visual Studio, I've used the CoCreateGuid function.
If you are locked into a 32-bit integer another option option is a hash table. If each XML element is unique, then a hashing function could generate a unique hash value. Depending on the size of your data set there is still a small probability of collision. The one I've used that seems to have a pretty low collision rate with the data set that I've worked with is called the Jenkins hash function