How to run multiple Groovy unit tests - unit-testing

I want to keep my groovy source files in their own directory, with the tests being in a separate directory.
I have the directory structure as follows:
.
├── build
│   └── Messenger.class
├── build.xml
├── ivy.xml
├── lib
├── src
│   └── com
│   └── myapp
│   └── Messenger.groovy
└── test
└── unit
├── AnotherTest.groovy
└── MessengerTest.groovy
I can successfully run one test by using the groovy command and specifying the class path for the units under test using -cp to point to build/ but how do I run all the tests in the directory?

Tou can run all unit test with command:
grails test-app unit:
If you have unit, integration, functional... tests you can run all tests with command:
grails test-app

I am new to groovy, but I wrote my own test runner and put it in root directory of my project. Source code:
import groovy.util.GroovyTestSuite
import junit.textui.TestRunner
import junit.framework.TestResult
import static groovy.io.FileType.FILES
public class MyTestRunner {
public static ArrayList getTestFilesPaths(String test_dir) {
// gets list of absolute test file paths
ArrayList testFilesPaths = new ArrayList();
new File(test_dir).eachFileRecurse(FILES) {
if(it.name.endsWith(".groovy")) {
testFilesPaths.add(it.absolutePath)
}
}
return testFilesPaths;
}
public static GroovyTestSuite getTestSuite(ArrayList testFilesPaths) {
// creates test suite using absolute test file paths
GroovyTestSuite suite = new GroovyTestSuite();
testFilesPaths.each {
suite.addTestSuite(suite.compile(it));
}
return suite;
}
public static void runTests(GroovyTestSuite suite) {
// runs test in test suite
TestResult result = TestRunner.run(suite);
// if tests fail return exit code non equal to 0 indicating that
// tests fail it helps if one of your build step is to test files
if (!result.wasSuccessful()) {
System.exit(1);
}
}
}
ArrayList testFilesPaths = MyTestRunner.getTestFilesPaths("tests");
GroovyTestSuite suite = MyTestRunner.getTestSuite(testFilesPaths);
MyTestRunner.runTests(suite)
if you try to use this be aware that if it fails it is most likely that getTestFilesPaths is not working properly.
My directory structure
.
├── test_runner.groovy
├── src
│ └── ...
└── tests
└── Test1.groovy
└── someDir
├── Test2.groovy
└── Test3.groovy
How to run
From the same directory where test_runner.groovy is run:
groovy test_runner.groovy

Related

How to run database setup only once from multiple Go packages?

I'm trying to create some objects in my database, so that my tests can have some data to work with. I've put my setup logic into a package testsetup. However, I've discovered that go test runs each package as a totally separate instance, so that even though I'm using sync.Once in my testsetup package, Setup still runs multiple times because each package's tests run as a separate Go instance. I really want to keep running my tests in parallel because it's a lot faster, so I'm not currently considering turning off parallelization. Is there a clean way I can do this?
I'm even starting to consider dirty hacks at this point, like using a shell script to implement os-level synchronization.
Here's my package structure:
testsetup
testsetup.go
package1
package1.go
package1_test.go
package2
package2.go
package2_test.go
And here's a simplified version of my testsetup function:
var onceSetup sync.Once
var data model.MockData
func Setup() model.MockData {
onceSetup.Do(createData)
return data
}
func createData() {
// Do some SQL calls to create the objects. We only want to do this once.
data = model.Data{
Object1: ...,
Object2: ...,
}
}
It can be done but it may not be worth it, you'll have to decide that for yourself.
You'll need a package that implements a "test registry" and a "test runner", and another package that is the "entrypoint" that ties it all together and starts the runner.
The resulting structure could look something like this:
../module
├── app
│   ├── pkg1
│   │   ├── foo.go
│   │   ├── ...
│   │   └── tests
│   │   ├── test_foo.go
│   │   ├── ...
│   │   └── pkg1_test.go
│   └── pkg2
│   ├── ...
│   ├── bar.go
│   └── tests
│   ├── ...
│   ├── test_bar.go
│   └── pkg2_test.go
├── go.mod
├── internal
│   └── testutil
│   ├── registry.go # the test registry
│   └── runner.go # the test runner
└── tests
└── start_test.go # the test entrypoint
First, let's consider what the entrypoint will look like once this is done. It may be that you don't like what you see, in that case you should probably ignore the rest of the answer.
File module/tests/start_test.go:
package tests
import (
"testing"
// Use the blank identifier for "side-effect-only" imports
_ "module/app/pkg1/tests"
_ "module/app/pkg2/tests"
// ...
"module/internal/testutil"
)
func Test(t *testing.T) {
testutil.TestAll(t)
}
Next, the registry in module/internal/testutil/registry.go:
package testutil
import (
"path/filepath"
"runtime"
"testing"
)
// v: the directory of a package
// v: the files in a directory
// v: the tests in a file
var tests = make(map[string][][]func(*testing.T))
func Register(ft ...func(*testing.T)) int {
// Use the directory of the Caller's file
// to map the tests. Why this can be useful
// will be shown later.
_, f, _, _ := runtime.Caller(1)
dir := filepath.Dir(f)
tests[dir] = append(tests[dir], ft)
// This is not necessary, but a function with a return
// can be used in a top-level variable declaration which
// can be used to avoid unnecessary init() functions.
return 0
}
The runner in module/internal/testutil/runner.go:
package testutil
import (
"testing"
)
func TestAll(t *testing.T) {
// TODO setup ...
defer func() {
// TODO teardown ...
}()
// run
for _, dir := range tests {
for _, file := range dir {
for _, test := range file {
test(t)
}
}
}
}
Now the individual packages, e.g. module/app/pkg1/tests/test_foo.go:
package tests
import (
"testing"
"module/internal/testutil"
)
var _ = testutil.Register(
TestFoo1,
TestFoo2,
)
func TestFoo1(t *testing.T) {
// ...
}
func TestFoo2(t *testing.T) {
// ...
}
That's it, you can now go to the module/tests "entrypoint" and run:
go test
ADDENDUM #1
If you want to retain the ability to test the individual packages separately
then that can be integrated as well.
First, add a new function to the runner in module/internal/testutil/runner.go:
package testutil
import (
// ...
"path/filepath"
"runtime"
)
// ...
func TestPkg(t *testing.T) {
// Now the directory of the Caller's file
// comes in handy. We can use it to make
// sure no other tests but the caller's
// will get executed.
_, f, _, _ := runtime.Caller(1)
dir := filepath.Dir(f)
// TODO setup ...
defer func() {
// TODO teardown ...
}()
// run
for _, file := range tests[dir] {
for _, test := range file {
test(t)
}
}
}
And in the individual test package add a single test file, e.g. module/app/pkg1/tests/pkg1_test.go:
package tests
import (
"testing"
"module/internal/testutil"
)
func Test(t *testing.T) {
testutil.TestPkg(t)
}
That's it, now you can cd into module/app/pkg1/tests and run:
go test
ADDENDUM #2
Now, with the individual packages having their own _test.go file, you are back to square one if you want to use go test module/... to execute all the tests in the module, since that would not only run the entrypoint but also cause the individual test packages to be executed individually.
You can work around that problem with a simple environment variable however. Just a small adjustment to the testutil.TestPkg function:
package testutil
import (
// ...
"os"
)
// ...
func TestPkg(t *testing.T) {
if os.Getenv("skippkg") == "yes" {
return
}
// ...
}
And now...
# ... the following will work as you'd expect
skippkg=yes go test module/...
go test module/tests
go test module/app/pkg1/tests
Is there some sort of blocking mechanism in your testsetup? I would think that each package would run its tests in parallel still and run what they need from testsetup in parallel. Otherwise you could make it like this:
testsetup
testsetup.go
packages_test.go
package1
package1.go
package2
package2.go
And then in testpackage/packages_test.go, is where you run your tests, importing the code in package1 and package2
It could look something like this:
package testpackage
import (
p1 "project/root/package1"
p2 "project/root/package2"
)
func TestPackages(t *testing.T) {
setup := Setup()
t.Parallel()
t.Run("Package1Test", func(t *testing.T) { package1Test(t, setup) })
t.Run("Package2Test", func(t *testing.T) { package2Test(t, setup) })
}
func package1Test(t *testing.T, d model.MockData) {
err := p1.RunYourFunc(d.data)
require.NoError(t, err)
}
func package2Test(t *testing.T, d model.MockData) {
err := p2.OtherFunc(d.data)
require.NoError(t, err)
}

How to properly server static files from a Flask server?

What is the proper way of serving static files (images, PDFs, Docs etc) from a flask server?
I have used the send_from_directory method before and it works fine. Here is my implementation:
#app.route('/public/assignments/<path:filename>')
def file(filename):
return send_from_directory("./public/assignments/", filename, as_attachment=True)
However if I have multiple different folders, it can get a bit hectic and repetitive because you are essentially writing the same code but for different file locations - meaning if I wanted to display files for a user instead of an assignment, I'd have to change it to /public/users/<path:filename> instead of /public/assignments/<path:filename>.
The way I thought of solving this is essentially making a /file/<path:filepath> route, where the filepath is the entire path to the destination folder + the file name and extension, instead of just the file name and extension. Then I did some formatting and separated the parent directory from the file itself and used that data when calling the send_from_directory function:
#app.route('/file/<path:filepath>', methods=["GET"])
def general_static_files(filepath):
filepath = filepath.split("/")
_dir = ""
for i, p in enumerate(filepath):
if i < len(filepath) - 1:
_dir = _dir + (p + "/")
return send_from_directory(("./" + _dir), filepath[len(filepath) - 1], as_attachment=True)
if we simulate the following request to this route:
curl http://127.0.0.1:5000/file/public/files/jobs/images/job_43_image_1.jpg
the _dir variable will hold the ./public/files/jobs/images/ value, and then filepath[len(filepath) - 1] holds the job_43_image_1.jpg value.
If i hit this route, I get a 404 - Not Found response, but all the code in the route body is being executed.
I suspect that the send_from_directory function is the reason why I'm getting a 404 - Not Found. However, I do have the image job_43_image_1.jpg stored inside the /public/files/jobs/images/ directory.
I'm afraid I don't see a lot I can do here except hope that someone has encountered the same issue/problem and found a way to fix it.
Here is the folder tree:
├── [2050] app.py
├── [2050] public
│   ├── [2050] etc
│   └── [2050] files
│   ├── [2050] jobs
│   │   ├── [2050] files
│   │   └── [2050] images
│   │   ├── [2050] job_41_image_decline_1.jpg
│   │   ├── [2050] job_41_image_decline_2554.jpg
│   │   ├── [2050] ...
│   ├── [2050] shop
│   └── [2050] videos
└── [2050] server_crash.log
Edit 1: I have set up the static_url_path. I have no reason to believe that that could be the cause of my problem.
Edit 2: Added tree
Pass these arguments when you initialise the app:
app = Flask(__name__, static_folder='public',
static_url_path='frontend_public' )
This would make the file public/blah.txt available at http://example.com/frontend_public/blah.txt.
static_folder sets the folder on the filesystem
static_url_path sets the path used within the URL
If neither of the variables are set, it defaults to 'static' for both.
Hopefully this is what you're asking.

Importing files from other directory in python?

I have following directory structure:
A
|
|--B--Hello.py
|
|--C--Message.py
Now if the path of root directory A is not fixed, how can i import "Hello.py" from B to "Message.py" in C.
At first I suggest to add empty __init__.py file into every directory with python sources. It will prevent many issues with imports because this is how the packages work in Python:
In your case it this should look like this:
A
├── B
│   ├── Hello.py
│   └── __init__.py
├── C
│   ├── Message.py
│   └── __init__.py
└── __init__.py
Let's say the Hello.py contains the function foo:
def foo():
return 'bar'
and the Message.py tries to use it:
from ..B.Hello import foo
print(foo())
The first way to make it work is to let the Python interpreter to do his job and to handle package constructing:
~ $ python -m A.C.Message
Another option is to add your Hello.py file into list of known sources with the following code:
# Message.py file
import sys, os
sys.path.insert(0, os.path.abspath('..'))
from B.Hello import foo
print(foo())
In this case you can execute it with
~/A/C $ python Message.py

meteor cucumber test server.call in step definition Error: Method not found [404]

I am new to Meteor Cucumber I am trying to do a basic test
Check a new user
Here is the step definition code
this.Given(/^I am a new user$/, function () {
server.call('fixtures/reset').then(function() {
server.call('fixtures/seedData');
});
});
I get
Error: Method not found [404] ...
at World. (/tests/cucumber/features/step_definitions/static_page.js:17:20)
which points to the first server.call (column 20 is the c of call).
Here is the feature
Given I am a new user
Here is the fixture
(function () {
'use strict';
Meteor.methods({
'fixtures/reset': function () {
Meteor.users.remove({});
},
'fixtures/seedData': function () {
Accounts.createUser({
email: "bob#example.com",
password: "testtest"
});
}
});
})();
Here is the package.js
Package.describe({
name: 'fixtures',
version: '0.0.1',
summary: '',
git: '',
documentation: null,
debugOnly: true
});
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.use('ecmascript');
api.addFiles(['fixtures.js'],['server']);
});
I don't understand why this code is failing
It is based on http://www.mhurwi.com/a-basic-cucumber-meteor-tutorial/
Why do you have a package for your tests? That's not necessary. At the root level of your Meteor app folder, make a directory called "tests". My structure looks like this:
tests
└── cucumber
├── features
│   ├── artist
│   │   ├── artist-login.feature
│   │   └── step_definitions
│   │   └── artist-login.js
│   ├── support
│   │   └── hooks.js
│   └── viewer
└── fixtures
└── artist-fixtures.js
You don't need any closures in your fixtures file. This is mine:
Meteor.methods({
'reset': function () {
Meteor.users.remove({});
},
'createTestAccount': function () {
Accounts.createUser({
email: 'test#user.com',
password: 'test123',
profile: {
firstName: 'Test',
lastName: 'User'
}
});
},
'isLoggedIn': function () {
return !!Meteor.userId();
}
});
If you're writing a Meteor package and want to test it, use TinyTest.

Eunit error with multiple apps

I have the following directory structure:
myapp
├── apps
│   ├── myapp
│   ├── myotherapp
│   └── myapp_common
├── deps
│   ├── cowboy
......
I run eunit using rebar as follows in the main myapp directory:
./rebar skip_deps=true eunit
It correctly runs eunit for three apps in apps/. After that it tries to run eunit in the parent myapp directory and throws the following error:
......
==> myapp (eunit)
ERROR: eunit failed while processing /home/msheikh/myapp: {'EXIT',{{badmatch,{error,{1,
"cp: missing destination file operand after `.eunit'\nTry `cp --help' for more information.\n"}}},
[{rebar_file_utils,cp_r,2,[]},
{rebar_eunit,eunit,2,[]},
{rebar_core,run_modules,4,[]},
{rebar_core,execute,4,[]},
{rebar_core,process_dir,4,[]},
{rebar_core,process_commands,2,[]},
{rebar,main,1,[]},
{escript,run,2,[{file,"escript.erl"},{line,727}]}]}}
Question: How can I fix this or prevent eunit from running for the parent myapp directory?
The rebar.config file in the main myapp directory looks like this:
{lib_dirs, ["deps", "apps"]}.
{deps, [
{lager, ".*", {git, "https://github.com/basho/lager.git", {branch, "master"}}},
{jsx, ".*", {git, "git://github.com/talentdeficit/jsx.git", {tag, "v0.9.0"}}},
{cowboy, "", {git, "git://github.com/extend/cowboy.git", {branch, "master"}}},
....
]}.
{require_otp_vsn, "R15"}.
{escript_incl_apps, [getopt]}.
{erl_opts, [
debug_info,
warn_missing_spec,
{parse_transform, lager_transform}
]}.
{eunit_opts, [verbose]}.
{validate_app_modules, false}.
{sub_dirs, [
"apps/myapp/",
"apps/myotherapp/",
"apps/myapp_common/"]}.
I have the same project structure, and it works.
Are you sure you don't have src, test, ebin folders in the top-level directory?
If not, what happens if you mkdir .eunit? (I am not suggesting to keep this, but go looking for a solution from there).