gtest unit tests target configuration file path - c++

In my C++ application, I have a text file (dataFile.txt) that is installed on the Linux target machine in the following path:
/SoftwareHomeDir/Configuration/Application/dataFile.txt
This file exists on my Rational ClearCase source code environment under the path:
/ProjectName/config/Application/dataFile.txt
I am developping a unitTest in gtest that does following:
Read a specific data from dataFile.txt , if the data does not exist than write it into the file.
1) I am avoiding to create an environment variable to check whether I am in the compilation environment or the target machine. Then add additional test code in the final release. I really want to separate test code from final code.
2) I am not using any IDE (no visual studio, no qt, etc.), just notepad++
3) The compilatio. server is shared (access with a username, however the root folder "/" is shared. Which means that if I create the path "/SoftwareHomeDir/Confiugration/Application/dataFile.txt", it will be visible by all users, and if another user is running his gtest unitTest, he may overwrite my file.
4) In the final code, the path to the dataFile is hard coded, and it is very costly (will take few seconds to run) to implement a filesearch(filename) method to look for the file in the entire hard drive before reading the file.
Question:
I am looking for a solution to unit-test my code in the compilation environment that is using /ProjectName/config/Application/dataFile.txt

The solution to my problem was to combine gmock with gtest as described by the link
https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#delegating-calls-to-a-fake
The only modification I made to my code is that instead of defining the path to the configuration data using #define, I created a function getConfigFilePath() that returns the hardcoded path of the configuration file in the installed application. From here, I mocked the class and in my mock, I call a fake getConfigFilePath() that returns, when the real code is executing, the hardcoded path of the config file in the project tree in ClearCase. This is precisely what I was looking for.

Related

pytest: robust file path of a txt file used in tests

During a pytest fixture, what is the best way to robustly get the location of a text file for users that may specify different working directories at runtime e.g. I want a person using the cmd line in the test fixture directory find the file as well as an integration server which may work in the project's root. Can I somehow include the text file in a module? What are best practices for including and getting access to non .py files?
I am aware of BASE_DIR = os.path.dirname(os.path.dirname(__file__)), but I am not sure if this will always refer to the same directory given a particular way of running the test suite.
os.path.dirname(os.path.abspath(__file__)) (which is what I think you meant above) worked fine for me so far - it should work as long as Python can figure the path of the file, and with pytest I can't imagine a scenario where that wouldn't be true.

Using AsConfigured and still be able to get UnitTest results in TFS

So I am running into an issue when I go to build my projects using tfs build controller using the Output location "AsConfigred" it will not detect my unit tests. Let me give a little info on my setup.
TFS 2013 Update 2, Default Process Template
Here is a few screenshots that can hopefully help fill in what I can't in typing. I am copying my build out to a file share on our network so that we can use other utilities use the output. I don't want to use "PerProject" or "SingleFolder" because they mess up the file structure we have configured (These both will run the tests). So i have the files copy to folder names "SingleOutputFolder" which is a child of the DropLocation. I would like to be able to run from the drop folder or run from the bin folder for each of my tests (I don't care which). However it doesn't seem to detect/run ANY of the tests. Any help would be greatly appreciated. Please let me know if you need any additional information.
I have tried using ***test*.dll, Install\SingleFolderOutput**.test.dll, and $(TF_BUILD_DROPLOCATION)\Install\SingleFolderOutput*test*.dll
But I am not sure what variables are available and understand where the scope of its execution is.
Given that you're using Build Output location set to AsConfigured you have to change the default values of the Test sources spec setting to allow build to find the test libraries in the bin folders. Here's an example.
If the full path to the unit test libraries is:
E:\Builds\7\<TFS Team Project>\<Build Definition>\src\<Unit Test Project>\bin\Release\*test*.dll
use
..\src\*UnitTest*\bin\*\*test*.dll;
This question was asked on MSDN forums here.
MSDN Forums Suggested Workaround
The suggested workaround in the accepted answer (as of 8 a.m. on June 20) is to specify the full path to the test projects' binary folders: For example:
C:\Builds\{agentId}\{teamProjectName}\{buildDefinitionName}\src\{solutionName}\{testProjectName}\bin*\Debug\*test*.dll*
which really should have been shown as
{agentWorkingFolder}\src\{relativePathToTestProjectBinariesFolder}\*test*.dll
However this approach is very brittle, for the following reasons:
Any new test projects you add to the solution will not be executed until you add them to the build definition's list of test sources:
It will break under any of the following circumstances:
the build definition is renamed
the working folder in build agent properties is modified
you have multiple build agents, and a different agent than the one you specified in {id} runs the build
Improved Workaround
My workaround mitigates the issues listed in #2 (can't do anything about #1).
In the path specified above, replace the initial part:
{agentWorkingFolder}
with
..
so you have
..\src\{relativePathToTestProjectBinariesFolder}\*test*.dll
This works because the internal working directory is apparently the \binaries\ folder that is a sibling of the \src\ folder. Navigating up to the parent folder (whatever it is named, we don't care) and back in to \src\ before specifying the path to the test projects binaries does the trick.
Note: If you have multiple test projects, you add additional entries, separated with semicolons:
..\src\{relativePathToTestProjectONEBinariesFolder}\*test*.dll;..\src\{relativePathToTestProjectTWOBinariesFolder}\*test*.dll;..\src\{relativePathToTestProjectTHREEBinariesFolder}\*test*.dll;
What I ended up doing was adding a post build event to copy all of the test.dll into the staging location folder in the specific build that is basically equivalent to where it would go on a SingleFolder build and do that on each test project.
if "$(TeamBuildOutDir)" == "" (
echo "Building Interactively not in TFS"
) else (
echo "Building in TFS"
xcopy "$(TargetDir)*.*" "$(TeamBuildBinaries)\" /Y /E /S
)
MSBUILD parameter in the build def that told it to basically drop in the folder that TFS looks for them.
/p:TeamBuildBinaries="$(TF_BUILD_BINARIESDIRECTORY)"
Kept the default Test assembly file specification:
**\*test*.dll
View this link for the information on the variable that I used and what relative path it exists at.
Another solution is to do the reverse.
Leave all of the files in the root so that all of the built in functionality works. There is more than just test execution in there. What about static code analysis, impact analysis..among others. You would have to do something custom for them all.
Instead use a pre-drop powershell script to create your Install arrangement from the root files.
If it is an application then you can use the _ApplicationFolder Nuget package to create an _PublishApplications folder same as you get for web applications.

Gradle project version property from Java source

In my application I maintain the 'user-frendly' version as a public String constant in the main class.
Is it possible to retrieve this variables in the build.gradle to set the version property of the project? Currently I have to do this manually, what of course can lead to problems.
Correct way of maintaining "user-friendly" version would be version.properties file, stored in your source tree. E.g., under src/main/resources. Then you can load this properties file in Gradle script:
def config = new ConfigSlurper().parse(new File("src/main/resources/version.properties").toURL())
println(config.versionNumber)
I've plussed Nikita's answer, which is great.
But, firstly, File.toURL() is now deprecated. Something like this would be preferable:
ConfigObject conf = new ConfigSlurper().parse( file("src/main/resources/version.properties").toURI().toURL());
Secondly, note file( ... here, not new File( ... if this line is to be included in build.gradle. The former makes a File relative to the path of the root directory of your Gradle project and is in fact a method of Gradle interface Project. It's worth knowing that every method or property in build.gradle which appears to "come from nowhere" is in fact a method or property of an underlying, "invisible" Gradle Project instance.
If you put new File( "src/main... ") in build.gradle as in Nikita's answer you would in fact not notice any problems if running your Gradle task from a console with current directory the project/root directory... but (according to my experiments) if using the GradleTasks window in Eclipse, for example, you would then be creating a File path relative to the directory where Eclipse was running from... and this would give an error message saying "system cannot find the path specified".
Using file( ..., therefore, you can then go (in build.gradle):
version = conf.versionNumber
NB version here is another property of Project... but you'll be mystified if you look at the above Javadoc for Project, because it's not there! However, you will see getVersion() and setVersion(...). With Groovy every property automatically gets given, by Groovy magic, its own getter and setter method. I took a week out to learn a bit of Groovy, which is actually a fantastic language, and familiarising yourself with it a bit is highly recommended, and makes the learning curve of Gradle substantially less painful.
You can however find the version property in the DSL (domain-specific language) API for Gradle class Project here.
The file version.properties would typically contain something like this:
versionNumber='1.0.0'
NB accessing version from your code ... if you wanted to access this version number from your app code (or test code), you would indeed use new File( ...:
ConfigObject conf = new ConfigSlurper().parse( new File("src/main/resources/version.properties").toURI().toURL());
as in Nikita's answer.

TFS Build and absolute path in app.config

first, I'd like to apologize for my english, it's not my 1st language !
I'm a total n00b in the wonderful world of TFS Build (2010), and I've got a problem.
I'll try to explain it to you using a simple example (but my actual situation is much more complicated).
I have a project with a console application "MyApp1", its location on my computer is "D:\MyProjets\MyApp1".
I have another project "Res" which contains only resources, including a file named emailTemplate.html.
My project "MyApp1" uses this file. Therefore, in the "App.config" file there's a key that stores the path of this resource : "D:\MyProjets\Res\emailTemplate.html"
Finally, I have a test for that application "MyApp1". This test checks if an e-mail has been sent. To send the e-mail "MyApp1" will need the file "emailTemplate.html", and will use the key in the configuration file to find it.
When I run the test on my computer : everything's ok.
But if I build the solution with TFS Build, when the tests are run I have a problem with this resource. During the build, the source files are copied in a directory (for example "D:\Build\1\My build projet\Sources\MyProjets\Res", and therefore "MyApp1" will look for "emailTemplate.html" in "D:\MyProjets\Res\emailTemplate.html" (configuration file) and of course won't be able to find it.
How should I do ?
I already know that my project shouldn't work with resources this way, but it's almost impossible for us to change that now, since it's the way we've been working in my company for a loooong time...
I thought about modifying the BuildProcessTemplate to force the Build server to run a getLatest on the Res projects exactly where I want. But I don't know if it's a good idea, or if it's even possible...
Thanks a lot for your help ! :)
Edit your build definition to include the "Res" project directory in the workspace as well. It should be automatically download/updated at each build (if you use any of the default process templates), and as long as you use relative paths in your tests you should be fine.

Using Non-Local Data/Media Files with a C++ Application (gtkmm)

I'm beginning development on an acoustic spectrum analysis tool (inspired by spek) written in C++ with gtkmm (C++ bindings for the GTK+ GUI toolkit). I would imagine that I should know how to do this by now, however...
My directory structure is a-la-GNOME, e.g src/, data/, po/, man/. The specific situation that presented the need for my inquiry is the use of a GTK UI Manager that will be located in data/ui. For this specific situation, I want to be able to load the user-interface from this file in an install-independent manner (e.g. loading of the file does not depend on a make install; the executable may be run [and load the UI file] either from src/ after running make [thus compiling the sources into the selfsame exectuable] or from its install prefix). How would I refer to the UI file in my source code (keeping in mind that the loading of the file is not performed by creating a file object (fopen(...)) but rather by passing a file location as a string argument to (UIManager).add_ui_from_file(...))?
In addition to this particular situation of a UI file, how would I do similar references to files (i.e. databases, INI files, XML schemas) by using the autotools build process? Is there a piece of relevant Automake code to quickly set up a project to use this type of directory structure?
simply try to use both files (with the un-installed taking precedence):
if(!(UIManager).add_ui_from_file(../data/ui/mygui))
(UIManager).add_ui_from_file(/incalled/location/mygui)
In Glom, I created a helper function that tries both locations, with both locations being defined in the Makefile.am (this is simpler if you have only one Makefile.am, by using non-recursive automake, which is simpler anyway):
http://git.gnome.org/browse/glom/tree/glom/glade_utils.h#n38