Organizing tests in golang application and avoiding import cycles hell - testing

I'm currently experiencing a problem of architecting the application structure and its test infrastructure.
Here's a brief overview of the layout
<GOROOT>/src/myapp/controllers/
<GOROOT>/src/myapp/controllers/account.go
...
<GOROOT>/src/myapp/models/
<GOROOT>/src/myapp/models/account.go
<GOROOT>/src/myapp/models/account_test.go
...
<GOROOT>/src/myapp/components/
<GOROOT>/src/myapp/components/comp1/
<GOROOT>/src/myapp/components/comp1/impl.go
<GOROOT>/src/myapp/components/comp1/impl_test.go
<GOROOT>/src/myapp/components/
...
<GOROOT>/src/myapp/testutil/
<GOROOT>/src/myapp/testutil/database.go
<GOROOT>/src/myapp/testutil/models.go
...
Problem 1
File myapp/testutil/models.go contains some util functions used in the models/*_test.go tests.
The util functions actually do use the package myapp/models data structures and functions. Therefore we have an import cycle: account_test.go imports testutil package, which in its turn imports models.
The only clear solution here is to keep testutil/models.go right inside of models packages at the same package something like test_utils.go, which seems a bit clumsy to me. What would deb the best walkaround in such cases?
Problem 2
testutil package has some initialization of the comp1 (let's say it's a client to a 3rd party service). When we run a test comp1/impl_test.go the testutil package is imported, and it imports comp1 package as it's responsible for initialisation of the component. Same cyclic import hell. Moving initialisation to a every individual place in the test cases seems like a duplication of code. Still looking for some elegant solutions here...

Problem 1
If package testutils just provide utility functions used during testing of package module then just put those functions into models/testutils_test.go: Now these utility function will be included when running the models/*_test.go tests. No import cycle any longer.
This is your "only clear solution" and I cannot see anything "clumsy" with it.
Problem 2
Import cycle: Same as above.
Initialization: Your comp1/impl_test.go can provide a func init() so no need for duplicated code.
(The standard library is good source of how to test different stuff. IMHO code duplication in testing code is not one of the seven deadly sins.)

Related

Julia - When developing a pacakge, how to use an specific dependence only on the test?

I'm developing Julia code for a package, and in my code, the user is free to choose the optimizer he wants, hence, my code does not depend on the many optimizers available. Yet, when I implemented a test set, and to check if the functions are indeed working I need to import an optimizer. My question is then, how to use an specific dependence only on the test? Without making it a dependency on the package itself?
You can find out more about adding a project.toml and manifest.toml specifically for your test/ folder here: https://julialang.github.io/Pkg.jl/v1/creating-packages/#Test-specific-dependencies-in-Julia-1.2-and-above

What is the difference between "package" and "module" in Frege?

Hi I've been playing a little bit with Frege and I just noticed in some examples that package and module are used interchangeably:
package MyModuleOne where
and sometimes:
module MyModuleTwo where
When importing from one or the other I don't see any difference in the behavior of my program. Is there something I should keep in mind when using package or module keywords ?
Yes. It used to start out with package, but later I realized this was an obstacle when porting Haskell code which uses module. Hence I added module, and thus currently module and package are the same keyword, just spelled differently.
But the intention is, of course, to retire package sooner or later. So my advice would be to use module only.
(This reminds me that I probably have to update the lang spec with regard to this. Never mind.)

Go: test internal functions

Suppose I have a type MyType with a private method (mt *MyType) private() in a package mypackage.
I also have a directory tests, where I want to store tests for my package. This is how tests/mypackage_test.go looks like:
package mypackage_test
import (
"testing"
"myproj/mypackage"
)
func TestPrivate(t *testing.T) {
// Some test code
}
However, when I run go test I get the cannot refer to unexported field or method my package.(*MyType)."".private) error. I've googled a bit and found out that functions starting with lower case can not be seen outside their own package (and this seems to be true, 'cause upper case functions are freely callable from the tests).
I also read somewhere that adding <...>_internal_test.go to the test file could solve my problem like this (tests/mypackage_internal_test.go):
package mypackage
import (
"testing"
)
func TestPrivate(t *testing.T) {
mt := &MyType{}
// Some test code
}
But with this I only get undefined: MyType. So, my question: how can I test internal/private methods?
Why do you place your tests in a different package? The go testing mechanism uses _test as a suffix for test files so you can place tests in the same packages as the actual code, avoiding the problem you describe. Placing tests in a separate package is not idiomatic Go. Do not try to fight the Go conventions, it's not worth the effort and you are mostly going to lose the fight.
Go insists that files in the same folder belong to the same package, that is except for _test.go files. Moving your test code out of the package allows you to write tests as though you were a real user of the package. You cannot fiddle around with the internals, instead you focus on the exposed interface and are always thinking about any noise that you might be adding to your API.
And:
If you do need to unit test some internals, create another file with _internal_test.go as the suffix. Internal tests will necessarily be more brittle than your interface tests — but they’re a great way to ensure internal components are behaving, and are especially useful if you do test-driven development.
Source: https://medium.com/#matryer/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742
There are different opinions on how you should struct you tests within a golang project and I suggest you to read the blog above.

What is a good workflow for developing Julia modules with IPython/Jupyter?

I find myself frequently developing new Julia modules while at the same time using those modules for my work. So I'll have an IPython (Jupyter) notebook, with something like:
using DataFrames
using MyModule
Then I'll do something like:
x = myfunction(7, 3)
But I'll have to modify that function, and unfortunately by that point I can't simply do
using MyModule
again. I'm not really sure why; I thought that calling using simply declares available modules in order to make the global scope aware of them, and then when a name is actually needed, the runtime searches for the definition among the currently loaded modules (starting with Main).
So shouldn't using MyModule simply just refresh the definitions of the items in the already declared module? Why do I have to completely stop and restart the kernel in order to use my updated functions? (Is it because names are bound only once to functions that are declared using the function keyword?)
I've looked at Julia Workflow Tips, but I don't find the whole Tmp, tst.jl system very simple or elegant... at least for a notebook.
Any suggestions?
I think there's a lot of truth in this statement attributed to one of the Juno developers: Jupyter notebook is for working with data. Juno IDE is for working with code.
Jupyter is great for using modules in a notebook style that the output you're getting is reproducible. Juno and the REPL have less overhead that let you keep starting new sessions (faster testing, and fixes the problem you noted), have multiple tabs open to follow code around a complex module, and can use the debugger (in v0.5). They address different development issues for difference stages of use. I think you're pushing against the tide if you're using the wrong tool for the wrong job.

Module based project vs Normal project

I am writing code on top an established Enterprise application. I see that the application has 4 modules as shown below.
-Srk
-SrkEJB
-SrkUtils
-SrkWeb
I have gone through the code and I see that some modules are tiny for example: SrkEJB module has got just 2 EJBS. I don't see any reason to create a separate module for 2 Java classes.
I have simplified the above approach and is shown below.
Srk
- com.srk.utils
- com.srk.ejb
- com.srk.web
How is the first module based architecture different from the second from an architectural stand point? Generally, which is the followed mostly, when creating an application from scratch? If not, What could be the trade-offs of each of the approaches? I believe this is a not specific to Java alone.
I don't see any reason to create a separate module for 2 Java classes.
I believe this is an invalid chain of reasoning. You should create a separate module whenever you discover classes, related to the same subject. The number of classes is irrelevant here. You may have a module containing only one class, if the purpose of that class is really different from others.
The name of the package / module should clearly speak its purpose. So, module name "Srk" seems bad to me (I suppose "srk" is some kind of abbreviated company name and is not related to architecture).
The same may be related to "utils", which sounds very generic to me. It is impossible to tell, what are those utils about.