# Unit Testing Approach VTK TDD

**URL:** https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124
**Category:** Development
**Created:** [June 13, 2019, 9:59am UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124 "2019-06-13T09:59:40Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![joe.maliszewski](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/278dde/32.png) [@joe.maliszewski](https://discourse.vtk.org/u/joe.maliszewski)
#### Post date: [June 13, 2019, 9:59am UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124/1 "2019-06-13T09:59:40Z")

</div>

I have current set up a unit testing framework with CMake and Google Tests with vtk and qt.

I cant find much documentation or examples of how people are developing VTK applications with TDD.

Problems I am finding:

1. Its hard to test an output, as i have been currently verifying my algorithms with the rendered visuals in the render windows. Therefore a way i have tried to get round this is to test my vtk objects in my pipline to see if they have input and output connections, and if polydata-\>GetNumberOfPoints() \> 0. Is this the way to correct way to test, or is this overkill?

2. Should I test every vtk object in my pipeline?

3. How granular should my functions be? in theory i could create a function for each stage of the pipeline (eg Create\_mapper(), Create\_render\_add\_mapper(Create\_mapper())) which is clearly the wrong why to do it.

4. i’m finding it difficult to distinguish if I am doing TDD or just putting unnecessary checks in my pipeline.

Myself, and i’m sure many others are looking to move over to TDD/unit testing in order to produce more robust code with a lower bug rate. If there is anyone with any experience with this, or has any advice, I would be very appreciative, as I would love to understand your VTK TDD approach.

If you had a simple example, that would be fantastic!. For example: drawing a line (Shown Below) . How would anyone go about testing this. [https://vtk.org/Wiki/VTK/Examples/Cxx/GeometricObjects/Line](https://vtk.org/Wiki/VTK/Examples/Cxx/GeometricObjects/Line)

Many thanks in advance,

Joe

---

<div class="post-metadata">

### Author: ![joe.maliszewski](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/278dde/32.png) [@joe.maliszewski](https://discourse.vtk.org/u/joe.maliszewski)
#### Post date: [June 13, 2019, 11:24am UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124/2 "2019-06-13T11:24:35Z")

</div>

Current example for sphere

TEST.CXX

#include \<gtest/gtest.h\>  
#include “sphere.h”

#include \<vtkSphereSource.h\>  
#include \<vtkPolyData.h\>  
#include \<vtkSmartPointer.h\>  
#include \<vtkPolyDataMapper.h\>  
#include \<vtkActor.h\>  
#include \<vtkRenderWindow.h\>  
#include \<vtkRenderer.h\>  
#include \<vtkRenderWindowInteractor.h\>  
#include \<vtkNamedColors.h\>  
#include \<vtkProperty.h\>

//Sphere\_class\* SC\_PTR = get\_sphere\_obj();

Sphere\_class SC;  
bool test\_setup = false;

void setup\_test()  
{  
if (!test\_setup)  
{   
test\_setup = true;  
SC.draw\_sphere();  
}  
}

TEST(create\_sphere\_T1, sphere\_pipeline\_object\_exists)  
{  
setup\_test();  
int sum\_of\_working\_objects = 0;  
int expected\_num\_working\_objs = 6;

```
if (SC.source != NULL) { sum_of_working_objects++; }
if (SC.mapper != NULL) { sum_of_working_objects++; }
if (SC.renderer != NULL) { sum_of_working_objects++; }
if (SC.render_window != NULL) { sum_of_working_objects++; }
if (SC.interactor != NULL) { sum_of_working_objects++; }
if (SC.actor != NULL) { sum_of_working_objects++; }

ASSERT_EQ(expected_num_working_objs, sum_of_working_objects);

```

}

TEST(create\_sphere\_T2, sphere\_center\_at\_origin)  
{  
setup\_test();  
bool expected\_bool = false;  
bool actual\_bool = false;

```
double expected_COM_array[3] = { 0 };
double get_actual_array[3];

if (SC.centre_of_sphere[0] == expected_COM_array[0] && SC.centre_of_sphere[1] == expected_COM_array[1] && SC.centre_of_sphere[2] == expected_COM_array[2])
{
	actual_bool = true;
}

ASSERT_EQ(expected_bool, actual_bool) << "expected_COM_array: " << expected_COM_array[0] << " " << expected_COM_array[1] << " " << expected_COM_array[2] << " actual " << SC.centre_of_sphere[0] << " " << SC.centre_of_sphere[1] << " " << SC.centre_of_sphere[2];

```

}

TEST(create\_sphere\_T3, radius\_is\_5) {  
setup\_test();  
double expected\_COM = 5.0;  
ASSERT\_EQ(expected\_COM, SC.source-\>GetRadius());  
}

TEST(create\_sphere\_T4, sphere\_output\_has\_poly) {  
setup\_test();  
bool expected = true;  
bool actual = false;  
if (SC.source-\>GetOutput()-\>GetNumberOfPoints() \> 0 )  
{  
actual = true;  
}

```
ASSERT_EQ(expected, actual) << "num points : " << SC.source->GetOutput()->GetNumberOfPoints();

```

}

TEST(create\_sphere\_T5, mapper\_is\_connected) {  
setup\_test();  
int expected = 1;  
ASSERT\_EQ(expected, SC.mapper-\>GetTotalNumberOfInputConnections());  
}

TEST(create\_sphere\_T6, actor\_has\_mapper) {  
setup\_test();  
int expected = 1;  
ASSERT\_EQ(expected, SC.actor-\>GetMapper()-\>GetTotalNumberOfInputConnections());  
}

TEST(create\_sphere\_T6,renderer\_has\_actor) {  
setup\_test();  
int expected\_num\_items = 1;  
ASSERT\_EQ(expected\_num\_items, SC.renderer-\>GetActors()-\>GetNumberOfItems());  
}

TEST(create\_sphere\_T7,renderwindow\_has\_renderer) {  
setup\_test();  
int expected = 1;  
ASSERT\_EQ(expected, SC.render\_window-\>HasRenderer(SC.renderer)) \<\< "has renderer " \<\< SC.render\_window-\>HasRenderer(SC.renderer) \<\< endl;  
}

TEST(create\_sphere\_T7,renderwindow\_has\_interactor) {  
setup\_test();  
bool expected = true;  
bool actual = false;

```
if (SC.render_window->GetInteractor() != NULL)
{
	actual = true;
}

ASSERT_EQ(expected, actual);

```

}

CXX

#include \<vtkSphereSource.h\>  
#include \<vtkPolyData.h\>  
#include \<vtkSmartPointer.h\>  
#include \<vtkPolyDataMapper.h\>  
#include \<vtkActor.h\>  
#include \<vtkRenderWindow.h\>  
#include \<vtkRenderer.h\>  
#include \<vtkRenderWindowInteractor.h\>  
#include \<vtkNamedColors.h\>  
#include \<vtkProperty.h\>  
#include \<gtest/gtest.h\>  
#include “sphere.h”  
#include \<vtkConnectivityFilter.h\>  
#include \<gmock/gmock.h \>

int main(int argc, char\*argv[]) //int, char \*[])  
{  
testing::InitGoogleTest(&argc, argv);  
RUN\_ALL\_TESTS();  
}

void Sphere\_class::draw\_sphere()  
{

```
source->SetCenter(0, 0, 1);
source->Modified();
source->Update();
source->GetCenter(centre_of_sphere);

source->SetRadius(5.0);
source->Modified();
source->Update();

mapper->SetInputConnection(source->GetOutputPort());
mapper->Update();

actor->SetMapper(mapper);

renderer->AddActor(actor);

render_window->AddRenderer(renderer);
render_window->Render();

render_window->SetInteractor(interactor);
render_window->GetInteractor()->Start();

```

}

SPHERE.H

#ifndef H\_SPHERE  
#define H\_SPHERE

#include \<vtkSmartPointer.h\>  
#include \<vtkSphereSource.h\>  
#include \<vtkPolyDataMapper.h\>  
#include \<vtkActor.h\>  
#include \<vtkRenderWindow.h\>  
#include \<vtkRenderer.h\>  
#include \<vtkRenderWindowInteractor.h\>

class Sphere\_class  
{  
public:

```
vtkSmartPointer<vtkSphereSource> source = vtkSmartPointer<vtkSphereSource>::New();
vtkSmartPointer<vtkPolyDataMapper>mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> render_window = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();

double centre_of_sphere[3];

void draw_sphere();

```

};

#endif // !H\_SPHERE

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [June 13, 2019, 1:45pm UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124/3 "2019-06-13T13:45:17Z")

</div>

The 2000+ tests in VTK should answer your questions. If you need guidance on application level testing, you might have a look at the 1000+ test of [ParaView](https://www.paraview.org) or 600+ tests of [3D Slicer](https://www.slicer.org), which include testing of GUI widgets, complex workflows, event recording/replay based tests, etc.

> [@joe.maliszewski](#):
>
> Its hard to test an output, as i have been currently verifying my algorithms with the rendered visuals in the render windows

In general, it is indeed _very hard_ to verify that information displayed on the GUI is correct, so application testing often happens at lower levels: for example, you query GUI widgets about what they display instead of trying to do OCR or image comparison.

Since large part of VTK is about rendering, results must be checked visually. VTK does this pretty well, with its image-based regression testing infrastructure.

> [@joe.maliszewski](#):
>
> Should I test every vtk object in my pipeline?

Probably not. If you spend too much time with developing and maintaining automatic tests then you will not have enough time for everything else.

I usually determine the minimum level of testing by asking myself: **Would I be embarrassed if this was broken? If yes, then I add an automatic test for it.**

---

<div class="post-metadata">

### Author: ![joe.maliszewski](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/278dde/32.png) [@joe.maliszewski](https://discourse.vtk.org/u/joe.maliszewski)
#### Post date: [June 14, 2019, 9:55am UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124/4 "2019-06-14T09:55:50Z")

</div>

thank you for you response, it is very useful. Would It be possible to ask to be more specific?

would it be possible to receive some brief advise on how you might go about testing the sphere example. I would love to know via an example:

- How many tests are you using for a small function such as draw\_sphere?
- Which parts of it you are focusing on testing.
- Are you testing connection of VTK objects in your unit tests. Or would this come under integration tests. If so are these intergration tests included at the same time.
- Are you only testing logic.
- In order to test effectively would it be advised to split up the one large code in the sphere example, into smaller linked nested functions, in order to more effectively test, or is this necessary.
- Do you test intermediate local variables with the function, or just the return output of that function.
- If so, how do you make these locally define variables accessible to your tests class.

Many thanks in advance

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [June 14, 2019, 12:33pm UTC](https://discourse.vtk.org/t/unit-testing-approach-vtk-tdd/1124/5 "2019-06-14T12:33:30Z")

</div>

These are all good questions that you need to answer yourself, based on your project’s requirements and constraints. The goal is not to write perfect software but that is sufficiently good for its intended use.
