Go: test internal functions - testing

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.

Related

Karma-Jasmine: Conflicting source files

I have a pretty nice Gulp based Karma-Jasmine unit test workflow going. My question is about how to avoid source conflicts in one's tests. Without having to do anything, Karma-Jasmine has auto-magically exposed my src files to Jasmine and detected my tests. I can't see how this would be useful in a real codebase where things don't fit the happy-path.
Example: Create two files you would like to test that both implement a function with the same name, Test(). One returns true, the other false. Which one is your test actually testing? Do I have any control over this? I want to be able to test both (forget telling me about better JS design, that is obvious).

How can I locate resources for testing with Cargo?

I'm on a project interacting with files, and I would like to use text files to test my work. However tests aren't run from the tests/ directory, and thus I cannot reliably find them when running cargo run.
Does Cargo handle this by always running test from the root directory (which seems to be the case but I didn't find anything attesting it)?
The environment variable CARGO_MANIFEST_DIR can give you a stable base point to reference other files. Here, we assume that there's a resources/test directory at the top level of the crate:
use std::path::PathBuf;
fn main() {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/test");
println!("{}", d.display());
}
See also:
How can a Rust program access metadata from its Cargo package?
Building on top of the answer provided by #Shepmaster, presuming you intend to read the files for testing:
macro_rules! test_case {($fname:expr) => (
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/test/", $fname) // assumes Linux ('/')!
)}
which is simply used in your unit test like:
test_case!("json_data/example.json")
More or less accomplishes same goal but at compile-time (helpful for catching missing files) and fairly minimal. If someone knows how to make this compile-time and platform indepent - please feel welcome to edit.
See the full discussion in rust-lang issue #2841

Organizing tests in golang application and avoiding import cycles hell

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.)

The 'right' way to run unit tests in Clojure

Currently, I define the following function in the REPL at the start of a coding session:
(defn rt []
(let [tns 'my.namespace-test]
(use tns :reload-all)
(cojure.test/test-ns tns)))
And everytime I make a change I rerun the tests:
user=>(rt)
That been working moderately well for me. When I remove a test, I have to restart the REPL and redefine the method which is a little annoying. Also I've heard bad rumblings about using the use function like this. So my questions are:
Is using use this way going to cause me a problem down the line?
Is there a more idiomatic workflow than what I'm currently doing?
most people run
lein test
form a different terminal. Which guarantees that what is in the files is what is tested not what is in your memory. Using reload-all can lead to false passes if you have changed a function name and are still calling the old name somewhere.
calling use like that is not a problem in it's self, it just constrains you to not have any name conflicts if you use more namespaces in your tests. So long as you have one, it's ok.
using lein lets you specify unit and integration tests and easily run them in groups using the test-selectors feature.
I also run tests in my REPL. I like doing this because I have more control over the tests and it's faster due to the JVM already running. However, like you said, it's easy to get in trouble. In order to clean things up, I suggest taking a look at tools.namespace.
In particular, you can use clojure.tools.namespace.repl/refresh to reload files that have changed in your live REPL. There's alsorefresh-all to reload all the files on the classpath.
I add tools.namespace to my :dev profile in my ~/.lein/profiles.clj so that I have it there for every project. Then when you run lein repl, it will be included on the classpath, but it wont leak into your project's proper dependencies.
Another thing I'll do when I'm working on a test is to require it into my REPL and run it manually. A test is just a no-argument function, so you can invoke them as such.
I am so far impressed with lein-midje
$ lein midje :autotest
Starts a clojure process watching src and test files, reloads the associated namespaces and runs the tests relevant to the changed file (tracking dependencies). I use it with VimShell to open a split buffer in vim and have both the source and the test file open as well. I write a change to either one and the (relevant) tests are executed in the split pane.

how can I add code reuse to my Selenium tests?

Here's the situation that I'm working with:
Build tests in Selenium
Get all the tests running correctly (in Firefox)
Export all the tests to MSTest (so that each test can be run in IE, Chrome and FF)
If any test needs to be modified, do that editing in Selenium IDE
So it's a very one-way workflow. However, I'd now like to do a bit more automation. For instance, I'd like every test to run under each of two accounts. I'm getting into a maintenance issue. If I have 6 tests that I want to run under two accounts, suddenly I'd need 12 tests in the Selenium IDE tests. That's too much editing. But a ton of that code is exactly the same.
How can I share chunks of Selenium tests among tests? Should I use Selenium IDE to develop the test first time then never use it again (only doing edits in VS after that)?
Selenium code is very linear after you export it from the IDE.
For example (ignore syntax):
someTestMethod() {
selenium.open("http://someLoginPage.com");
selenium.type("usernameField", "foo");
selenium.type("passwordField", "bar");
selenium.click("loginButton");
selenium.waitForPageToLoad("30000");
assertTrue(selenium.isTextPresent("Welcome * foo"));
}
This is the login page. Every single one of your tests will have to use it. You should refactor it into a method.
someTestMethod(){
selenium.open("http://someLoginPage.com");
String username = "foo";
String password = "bar";
performLogin(username, password);
}
performLogin(String username, String password){
selenium.type("usernameField", username);
selenium.type("passwordField", password);
selenium.click("loginButton");
selenium.waitForPageToLoad("30000");
assertTrue(selenium.isTextPresent("Welcome * foo"));
}
The performLogin() method does not have to be in the same file as your test code itself. You can create a separate class for it with your methods and share it between your tests.
We have classes that correspond to certain functionalities on our UI. For example, we have many ways to search in our app. All methods that helps you with search functionality will be in the SearchUtil class.
Structuring your tests similarly will give you the following advantages:
If the UI changes (an id of a field), you go to your one method, update the id and you are good to go
If the flow of your logic changes you also have only one place to update
To test whether your changes worked, you only have to run one of the tests to verify. All other tests use the same code so it should work.
A lot more expressive as you look at the code. With well named methods, you create a higher level of abstraction that is easier to read and understand.
Flexible and extensible! The possibilities are limitless. At this point you can use conditions, loops, exceptions, you can do your own reporting, etc...
This website is an excellent resource on what you are trying to accomplish.
Good Luck!
There are two aspects to consider regarding code reuse:
Eliminating code duplication in your own code base -- c_maker touched on this.
Eliminating code duplication from code generated by Selenium IDE.
I should point out that my comments lean heavily to the one-way workflow that you are using, jcollum, but even more so: I use IDE to generate code just once for a given test case. I never go back to the IDE to modify the test case and re-export it. (I do keep the IDE test case around as a diagnostic tool when I want to experiment with things while I am fine-tuning and customizing my test case in code (in my case, C#).
The reasons I favor using IDE tests only as a starting point are:
IDE tests will always have a lot of code duplication from one test to another; sometimes even within one test. That is just the nature of the beast.
In code I can make the test case more "user-friendly", i.e. I can encapsulate arcane locators within a meaningful-named property or method so it is much clearer what the test case is doing.
Working in code rather than the IDE just provides much greater flexibility.
So back to IDE-generated code: it always has massive amounts of duplication. Example:
verifyText "//form[#id='aspnetForm']/div[2]/div/div[2]/div[1]/span" Home
generates this block of code:
try
{
Assert.AreEqual("Home",
selenium.GetText("//form[#id='aspnetForm']/div[2]/div/div[2]/div[1]/span"));
}
catch (AssertionException e)
{
verificationErrors.Append(e.Message);
}
Each subsequent verifyText command generates an identical block of code, differing only by the two parameters.
My solution to this pungent code smell was to develop Selenium Sushi, a Visual Studio C# project template and library that lets you eliminate most if not all of this duplication. With the library I can simply write this one line of code to match the original line of code from the IDE test case:
Verify.AreEqual("Home",
selenium.GetText("//form[#id='aspnetForm']/div[2]/div/div[2]/div[1]/span"));
I have an extensive article covering this (Web Testing with Selenium Sushi: A Practical Guide and Toolset) that was just published on Simple-Talk.com in February, 2011.
You can also put some fragments or one-liners, e.g.
note( "now on page: " . $sel->get_location() . ", " . $sel->get_title() ;
into the "code snippets" collection of your IDE ( I use Eclipse).
That's not true reuse, but hey it works for me for throwaway testscripts or quick enhancements of existing testscripts.