I have a bazel project, call it foo, with Catch C++ unit tests that read files from a relative path.
The unit tests run fine in the foo project.
I'm using foo as an external dependency for another project, call it bar. I want the unit tests to work in bar, but in bar they cannot find the files.
What I do not understand is how to find the files in a project independent fashion. In project foo, the files are placed in:
~/.cache/<blah>/<blah>/<testname.runfiles>/__main__/source/
But in project bar, the files are placed in
~/.cache/<blah>/<blah>/<testname.runfiles>/__main__/external/bars_archive_name/source
The TEST_SRCDIR environment variable provided by bazel points to the directory, but that doesn't help because of the two different directory structures.
The unit test can not know bar's archive name (because that's specified in foo's WORKSPACE file), so it cannot find the files. The unit test also doesn't know if it should append external or not.
This seems like something that should be simple to do, so I hope that I'm missing something obvious.
How does your unit test depend on the files of project bar? Does the unit test require that the files are present under a relative path?
(Also, what language are your tests in? The more specific you can be about your project setup, the better I can help :))
Have you considered passing the location of test dependencies via flags / arguments to your test? If this is a possibility, Bazel can help resolve these paths as absolute paths if you use $(location) substitution.
For example, your test target might look like:
my_unit_test(
name = "test",
srcs = ["mysrc.file"],
deps = ["#bar//barproj/other.file"],
args = [
"$(location #bar//barproj/other.file)",
],
)
Please let me know if this is insufficient!
Related
I am using HWUT for unit testing and want to put my tests under version control. Adding the test code and the GOOD folder is obvious. But what about other files e.g. the ADM folder?
NEEDED
GOOD/*:
hwut-info.dat: If you specify it.
Makefile: If you specifiy it.
Your test scripts and source files that implement the test.
ADM/cache.fly: Optional; Only check-in if queries on past tests are to be accomplished without doing the tests.
NOT TO BE CHECKED-IN
OUT/*
Any result produced by 'make'
Any temporary log files
Note, SCMs usually have a 'prop:ignore' property, or an 'ignore' file. You may adapt this according to the information above.
I'm trying to use test support classes within my tests. I want these classes to be available for all different test types.
My directory structure is as follows;
/test/functional
/test/integration
/test/unit
/test/support
I have test helper classes within the /test/support folder that I would like to be available to each of the different test types.
I'm using GGTS and I've added the support folder to the classpath. But whenever I run my integration tests running 'test-app' I get a compiler 'unable to resolve class mypackage.support.MyClass
When I run my unit tests from within GGTS the support classes are found and used. I presume this is because the integration tests run my app in its own JVM.
Is there any way of telling grails to include my support package when running any of my tests?
I don't want my test support classes to be in my application source folders.
The reason that it works for your unit tests inside the IDE is that all source folders get compiled into one directory, and that is added to your classpath along with the jars GGTS picks up from the project dependencies. This is convenient but misleading, because it doesn't take into account that Grails uses different classpaths for run-app and each of the test phases, which you see when you run the integration tests. GGTS doesn't really run the tests; it runs the same grails test-app process that you do from the commandline, and captures its output and listens for build events so it can update its JUnit view.
It's possible to add extra jar files to the classpath for tests because you can hook into an Ant event and add it to the classpath before the tests start. But the compilation process is a lot more involved and it looks like it would be rather ugly/hackish to get it working, and would likely be brittle and stop working in the future when the Grails implementation changes.
Here are some specifics about why it'd be non-trivial. I was hoping that you could call GrailsProjectTestCompiler.compileTests() for your extra directory, but you need to compile it along with the test/unit directory for unit tests and the test/integration directory for integration tests, and the compiler (GrailsProjectTestCompiler) presumes that each test phase only needs to compile that one directory. That compiler uses Gant, and each test phase has its own Grailsc subclass (org.grails.test.compiler.GrailsTestCompiler and org.grails.test.compiler.GrailsIntegrationTestCompiler) registered as taskdefs. So it should be possible to subclass them and add logic to compile both the standard directory and the shared directory, and register those as replacements, but that requires also subclassing and reworking GrailsProjectTestRunner (which instantiates GrailsProjectTestCompiler), and hooking into an event to replace the projectTestRunner field in _GrailsTest.groovy with your custom one, and at this point my brain hurts and I don't want to think about this anymore :)
So instead of all this, I'd put the code in src/groovy and src/java, but in test-specific packages that make it easy to exclude the compiled classes from your WAR files. You can do that with a grails.war.resources closure in BuildConfig.groovy, e.g.
grails.war.resources = { stagingDir ->
println '\nDeleting test classes\n'
delete(verbose: true) {
// adjust as needed to only delete test-specific classes
fileset dir: stagingDir, includes: '**/test/**/*.class'
}
println '\nFinished deleting test classes\n'
}
Note that I have already read the layout convention.
In my lib directory I usually have a few libraries I could extract into their own package. Very often the code is not complete enough or / and I want to wait for a new package until I really want to reuse the code in another project.
I would really like to place the unit-test code, examples and doc in the same directory.
Example:
let's say I have a string-helper library in lib → lib/string-helper.
I would like to place my tests, examples and doc in lib/string-helper/tests, lib/string-helper/examplesand lib/string-helper/doc.
However the layout convention says that I should put them outside the lib directory.
This makes it unnecessarily hard to extract it into its own package. (pub serve even went into an endless loop when I ignored this and made my own package symbolic link)
How do you handle this?
The only valid place for tests is the my_package/test directory or any subdirectory of test.
I'd like to use Boost.Test for Test Driven Development.
I asked scons to create two executables, the main one, and the test one.
All my main project files are in ./src/, and all my test dedicated files are in ./test/
The problem is:
the main project object files are put in ./build/src/
the test project object files are put in ./build/test/
and in such a configuration my executable Test cannot link since all the main project object files (of the classes on which I perform my tests) are not in the same directory.
Do you have an idea how I could tweak my scons file so as the linking of the executable Test can use the object files in ./src./ ?
Below is my main.scons file:
import os
env=Environment(CPPPATH=['/usr/local/boost/boost_1_52_0/boost/','./src/'],
CPPDEFINES=[],
LIBPATH=['/usr/local/boost/boost_1_52_0/boost/libs/','.'],
LIBS=['boost_regex'],
CXXFLAGS="-std=c++0x")
env['ENV']['TERM'] = os.environ['TERM']
env.Program('Main', Glob('src/*.cpp'))
#
testEnv = env.Clone()
testEnv['CPPPATH'].append('./test/')
testEnv['LIBS'].append('boost_unit_test_framework')
testEnv.Program('Test', Glob('test/*.cpp'))
While the "duplicate object lists" approach is fine for simple projects, you may run into limitations in which your test code doesn't need to link against the entire object space of your main program. For example, to stub out a database layer that's not the focus of a particular unit test.
As an alternative, you can create (static) libraries of common code that you link against your primary executable and your test framework.
common_sources = ['src/foo.cpp', 'src/bar.cpp'] # or use Glob and then filter
env.Library("common", common_sources)
program_sources = ['src/main.cpp']
env.Program("my_program", program_sources, LIBS=['common'])
...
testEnv['LIBPATH'] = ['.'] # or wherever you build the library
testEnv.Program("unit_test", test_sources, LIBS=['common'])
This also avoids the duplicate main() problem that you mention because only the program_sources and test_sources lists should contain the appropriate file with the main routine.
I have continued searching, and found This post on the web which intrigued me, using the scons env.Object. Indeed this object contains the list of all target object files.
And with slight modifications I have the scons file that does what I wanted (though now I have a problem of dupplicated main function but that's another problem):
import os
env=Environment(CPPPATH=['/usr/local/boost/boost_1_52_0/boost/','./src/'],
CPPDEFINES=[],
LIBPATH=['/usr/local/boost/boost_1_52_0/boost/libs/','.'],
LIBS=['boost_regex'],
CXXFLAGS="-std=c++0x")
env['ENV']['TERM'] = os.environ['TERM']
# here I keep track of the main project object files
mainObjectFiles = env.Object( Glob('src/*.cpp'))
env.Program('PostgresCpp', mainObjectFiles)
#
testEnv = env.Clone()
testEnv['CPPPATH'].append('./test/')
testEnv['LIBS'].append('boost_unit_test_framework')
# here I append all needed object files
testObjectFiles = Glob('test/*.cpp')
testedObjectFiles = Glob('src/*.cpp')
allObjectFilesExceptMain = [x for x in mainObjectFiles if x != 'src/main.o']
allObjectFilesExceptMain.append(testObjectFiles)
testEnv.Program('Test',allObjectFiles)
Of course there is an option to turn it off (by default it is on.) However I like to be able to make incremental changes to the DLL while a copy of NUnit GUI is up.
However I couldn't find much documentation for this feature (apart from the need)
So the problem is like this
With Shadow copy enabled in NUnit,
my SUT (Dll) invokes an executable (also in the output folder ; via references). Now this executable needs certain configuration/modifier files to be in the same folder as the executable. How do I ensure that my reference modifier files are reachable by the executable during the test ?
Does NUnit shadow copy just the SUT dll or all the linked/referenced dlls/execs ? What do I need to do in the test setup such that any supporting files for the SUT are copied correctly?
I see that
executingAssembly.Codebase gives me the original output folder
executingAssembly.Location gives me the shadow copy folder.
I'm not sure if I am being lucid here - let me know if I need to update
The real issue is usually finding where they are during the tests.
Use this instead of Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location):
string exeDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
See Trouble with NUnit when determining the assembly's directory