Saturday 30 September 2017

TrafficControl: Refactoring trafficControl Class

This week-end, I've refactored the code to make it more testable and more agnostic.

The class trafficControl contains currently both GUI elements and logic for defining the traffic networks. Having both user interface and program logic in the same class will make automated testing difficult, and I need to refactor the code so that the user interface is separated from the logic.

The current structure of the program is:
  • main.cpp includes 
    • trafficControl.h, which includes
      • ui_trafficControl.h (this is autogenerated at run-time which causes problems when unit testing)
      • tcTrack
      • tcTrain
      • tcStation
      • trafficDataModel
      • trafficClock
I want to have a slightly different structure where the ui and the traffic logic is separated.
  • main.cpp includes
    • trafficControl which includes
      • ui_trafficControl.h (autogenerated)
      • tcNetworkControl which includes
        • tcTrack
        • tcTrain
        • tcStation
        • trafficDataModel
        • trafficClock
Steps taken for refactoring:
1. Remove ui references in tcTrack/tcTrain/tcStation/trafficDataModel/TrafficClock
2. Create tcNetworkControl files
3. Initiate tcNetworkControl
3. Move everything except ui elements to tcNetworkControl and update the references to it.
4 Copy reference to station/train/trackListModel to tcNetworkControl and also handleQMLObject
5. Ensure that the program works both when testing and in normal mode.

I also made some changes to the code that imports a file with network commands. Previously, that code opened a file, scanned it for all lines and interpreted them to commands. The new code scans a file, and parses the lines to another method in networkControl. With this change, I'll be able to define the network from other sources, such as test case and user input at runtime.

Monday 25 September 2017

TrafficControl: Integrating Google Test Into TrafficControl

After some struggle, I was finally successful with integrating Google Test into TrafficControl.

The steps are similar to the QtTest Integration blog post and the previous blog post:

I add two files to the "test" folder:
  • mainTest.cpp that is calling the test code and
  •  tst_tcUnitTests.h, where I have the test code.
In the pro file, I replace the QtTest directives with Google Test directives:

The mainTest.cpp is identical to the one in the Google Test example. The results can be seen below.

With Google Test, it is easy to sort test cases into different categories. That will be necessary as the number of test cases grow.

In the near future, I'll port the existing QtTest test cases to Google Test and implement the other test cases. I'll keep the existing QtTest files for now, even if I won't use them.

Wednesday 20 September 2017

TrafficControl: Analysing a Simple Google Test Project

To understand Google Test, I created a sample test application using Qt 5.9, that is using Microsoft Visual C 2015 and Google Test.



As for other Qt  projects, it is a good idea to start looking at the pro file:
+= means add module to project when compiling. -= means remove module.
The qt part is removed for this particular project. I assume that it is since no Qt code is to be tested in this project. It is still possible to compile and test when keeping qt in the project (by commenting out the removal clause on line 7). The same is for the app_bundle tag on line 5.

Google Test is added on the first line, using include statement. Let's have a look at the gtest_dependency.pri file.

The syntax is described in the Qt documentation
The syntax is descibedInitially, there are some checks for whether there is a defined GOOGLETEST_DIR on the computer. If not, the compiler will throw an error message to the build console. If there is such a directory, the test project will be compiled for GTest/GMock.

The test cases are listed in tst_firstgoogletestcase.h as separate functions. The tests are sorted into test cases and test sets, making it possible to have several test sets. This will be useful for me, since I want to sort the test cases in TrafficControl.

The cpp main file initiates the test suite.

In the next blog post, I'll try to import the test cases into the TrafficControl project.



Friday 15 September 2017

TrafficControl: Testing, Bug in Station Coordinate Check

When developing the unit tests, I'll only cover the interesting ones (the ones that exposes bugs in my code) in the blog.

One such test case is stationTest.invalidFloatCoordinatesAtCreation. 

The test case creates a station at 105°N, 13°E, and also another station at 55°N, 213°E. When testing, the result is:
The first coordinate is too big, but is parsed to the station anyways. In the second case, the coordinates are wrongly accepted.
The code is checking only the latitude for correct values. It also doesn't set the coordinate to 0, if the values are bad.

The new code that is passing is:

I also added a check in station::getLatitude and getLongitude, so that it returns 0 if hasCoordinates is false.

I'll investigate if I can define a more generic algorithm for validating coordinates, since that will be usefulwhen validating tracks in the future.

The location of 0 degrees N, 0 degrees E. It is tempting to let 0/0 indicate that there is no such station, but such assumptions can be dangerous.



When defining the test case, a part of me wanted to skip the check for coordinatues. That feeling is a very good reason to out extra focus on that test. 

Sunday 10 September 2017

Old Tracks: Future Trail over Hallandsåsen

I've discussed trails along old tracks in two blog posts, one for a line near Malmö and one for the High Line in Manhattan. A new trail is planned for the old tracks over Hallandsåsen in the northern parts of Skåne, Sweden.



The old tracks over Hallandsås were ready 1885, as a part of the line between Helsingborg and Halmstad on the Swedish west coast. The area is very beautiful with an astonoshing view of Båstad and the bay of Laholm just before entering the railway station of Båstad.

It was aso a very difficult track for the trains for some reasons. The incline is quite high, so some cargo trains needed to accelerate before approaching the ridge in order to have a chance to cross it. At some periods, stand-by locomotives were waiting in Förslöv and Båstad to give extra support for the trains.

During fall, wet leaves made the tracks very slippery, making it even harder to pass Hallandsåsen. The railway was a single track line with very limited top speed and a meeting point in Grevie, so a very limited number of trains could pass every hour.

It became more important to resolve that bottle-neck when the traffic volumes increased between Malmö and Göteborg, and a tunnel under the ridge was built between 1991 and 2015. The project became much more expensive and complicated than forecasted.

The first leg of the trail is planned to be ready in 2018 and it will be possible to visit it by bike, foot or riding a horse. 

An article (in Swedish) about the railway history on Bjärehalvön can be found here.

Tuesday 5 September 2017

TrafficControl: Testing Google Test

Now when I got QtTest working, I want to investigate how to use Google Test.

Google Test can be used with Qt Creator, and I need to find out how to use that for two reasons:

  1. Google Test might be more powerful with respect to functions,
  2. Google Test is more well-known than Qt Test and I will probably use it in future projects.

It's pretty simple to create a stand-alone Google Test application:

  1. First, I cloned cloning the GoogleTest repo using "git clone https://github.com/google/googletest.git", 
  2. After that, I created a Google Test project according to the Qt documentation.
  3. After compiling, the test is verifying and asserting the value of 0 and 1.


In the next blog post, I'll look into the files of the project and try to add test cases, and also to include Google test into TrafficControl.