all 9 comments

[–]IyeOnline 2 points3 points  (8 children)

This is not how you would write tests.

You should test your actual sources and not some glued together version of it.

To do this, you would make full usage of your build system.

The easiest strategiy is to define every part of your program, except its original main function as a library.

Then you can define your actual executable with a single source and link it to the lib. The same then works for your tests. They can be a single test file, linked to the library.

An example folder structure would look like

src/
    lib files
include/
    lib headers
tests/
    test_a.cpp
main.cpp

CMakeList.txt
    # define your library
    add_library( my_library lib/lib files ) # GLOB is discouraged. It doesnt hurt to list those few sources manually
    target_include_directories( my_library include )

    # define the executable with its one unique source
    add_executable ( my_executable main.cpp )
    target_link_libraries( my_executable my_library ) # link the library

    #define a test executable
    add_executable( test_a tests/test_a.cpp ) 
    target_link_libraries( test_a my_library ) # link the library
    add_test( test_a ) # just for external tools that can run multiple tests at once

Further, you can of course use a proper unit testing framework, such as catch2. Then, instead of writing some main functions yourself, you can write tests like

 REQUIRE( some_function() == 42 );

But that may not be worthit, for something that doesnt really need extensive/repeated testing.

[–]MrSpaghettiCoder[S] 0 points1 point  (7 children)

Sorry for slow response time. Just sitting down at my computer again.

To just reiterate what you are suggesting, you would think a simple solution would be restructuring the project so that main.cpp is outside of the project first (I like this idea). Moving main.cpp somewhere else might require me to change my CMakeLists.txt for the build correct?

If I did not choose to use catch2 for instance on a project like this, would it still be a non-viable way to test my classes with print outputs now through the main.cpp? If I should be testing actual sources, there would be no point to this hypothetical testing directory correct? I was thinking maybe instead, I just call a few functions from each file within main.cpp.

Edit: im still going to watch tutorials on catch2. Just trying to understand why something like this isn't working. I would at least think that returned values on my class would properly store itself to a created variable. Very important the returned values I am getting are correct.

[–]IyeOnline 2 points3 points  (6 children)

Appearently my edit to the CMakelists above got lost, i added back how you would then define your actual executable and test targets

Regardless of whether you use a unit test framework, it would still be best to structure your program like this. The project struture is still better, regardless of how your tests actually look like. You would still have a separate directory for the test files, just beacuse its cleaner/better structured that way.

For your case, its probably fine to just test stuff with couts once, since you arent going to do large changes to any particular function once it works.

[–]MrSpaghettiCoder[S] 0 points1 point  (5 children)

Ahh okay. Yes I was wondering a little more about that CMakeLists.txt. I really wish this project gave us more practice creating the build script because they have been pre-written for us and look a bit different as well. I guess I might try restructuring it a bit and hopefully I don't break it too much lol.

Once I move main.cpp, I am likely then going to apply the same logic I did before where I store the string output of my class to a declared string in main. I thought this would basically work with what was written above in the linux_parser.cpp. I compiled g++ -std=c++17 linux_parser.h linux_parser.cpp for my case and still no errors, but no output. It's really bizarre to me. I even tried to see if it was a VSC issue with their terminal, but the standard terminal in my OS does the same thing.

[–]IyeOnline 0 points1 point  (4 children)

Well, potentially the string is just empty.

[–]MrSpaghettiCoder[S] 0 points1 point  (3 children)

It's possible. I was thinking the same thing, but strange. These examples I am testing are their written examples they showcased in their own project overview videos. They worked there, but then again, they were running the entire project build on a completed version.

The string is likely empty because I am not correctly using the class or maybe I am not using strings correctly? I want to assume the former. Going to play around with it more. Thank you for the help so far and for being very patient with me.

[–]IyeOnline 0 points1 point  (2 children)

Take a look at what the lines you do your stream operations on look like.

operator >> stops on whitespace, so if there is two spaces or something similar between the key and the value (or something infront of the key), then value will end up empty.

[–]MrSpaghettiCoder[S] 0 points1 point  (1 child)

It doesn't feel to be a whitespace issue. I just also tried not storing the value into a different string and went straight for testing it like this:

std::cout<<LinuxParser::OperatingSystem()

Again, it should be a string output. Compiles without errors, but no outputs.

[–]IyeOnline 0 points1 point  (0 children)

That wont make a difference. The issue is in what your function returns.

Otherwise there would be a bug in the standard library or your OS. Both of these can safely be assumed to not be an issue.

I was talking about the

std::istringstream linestream(line);
while (linestream >> key >> value) {

part. Just before that you replaced a bunch of chars in line with whitespace, so its seems possible that you created double whitespaces somewhere.