I'm trying to create this directory structure in Maven Java project:
pom.xml
/src
/main
/java
/com
/XXX
Foo.java
Bar.java
/test
/java
/com
/XXX
FooTest.java
BarTest.java
/spikes <---- I'm not sure about the right English word for them
/com
/XXX
MockedHttpConnection.java
Thus, in two tests FooTest and BarTest I can use the same MockedHttpConnection, which is perfectly decoupled from them both, staying at the same time in the same package with them. What do you think about this approach? I have a feeling that I'm reinventing a wheel, but I can't find any patterns for this mechanism in Java.
If MockedHttpConnection is your own class I'd suggest you to store it under /test/java/com/testutil.
If it is third party class, just add jar to your classpath.
I'd sugget having it in your test package because in the end is testing code.
It's the same as the application. You don't just store your application main class under main. You store it and everything it needs to be executed.
Related
I am using Eclipse.
2 folders: src/test and src/main
Both have a package with same name: Academy.
The Academy package in src/test has in it a class name: Base.java
The Academy package in src/main has in it a class name: HomePage.java
In the HomePage.java class, extends Base is not detecting base class in it.
This is the code inside HomePage.java
package Academy;
import Academy.Base;
public class HomePage extends Base{
}
There is a red line on Academy.Base and on Base. It tells to make Base class, but it is already there. I tried to save the file. I tried to make new project too. Please Help. Thank you.
Here is the reference image:
You are using Maven as the build system for your Eclipse project.
Maven does not allow a class in your main tree to depend on a class in the test tree. It prevents this by telling the Java compiler and runtime that classes and resources in the test tree are not in the build time and runtime classpaths for the main code. That is why you are getting the compilation error.
Solution:
Move the Base.java class into "src/main/java/Academy" directory.
You commented:
It's just 2 packages with same name, inside 2 different folders. whether it's test or not, it should still inherit with extends.
Sorry ... but you are wrong. It does matter which tree you put the classes in. This is a Maven project, and Maven is "opinionated" about these things. For good reason, IMO. But either way, Maven's opinion takes precedence ... if you choose to use Maven.
There are a couple of other problems:
A package name should start with a lowercase letter. Read this for example.
Solution: Rename Academy to academy1.
Non-code resources should not be in a "java" directory. Non-code resources in a "java" source directory won't be on the runtime classpath ... and won't be included in (regular) JAR files.
Solution: Create a "resources" directory and put it there.
The import Academy.Base; is redundant. It is not necessary to import a class in the same package.
1 - Alternate solution: don't ask other people to work on your code, or help you with it. If other people don't ever need to read your code, it only matters to you what your code looks like. The compiler doesn't care. Only humans do.
The import was irrelevant.
Your src/main/java/, src/main/resources/ are packed for your main product, probably something like E2EProject1.jar.
Your src/test/java/, src/test/resources/ are packed in your unit tests, probably something like E2EProject1-test.jar. These test classes are kept outside your main product, but have the main product on the class path as dependency.
So it should be something like:
src/main/java/Base.java
src/test/resources/data.properties (or src/main/resources/)
That the packages are named identical is for being able to test (implicitly import) non-public, package private classes of src/main/java in unit test classes in src/test/java.
Solved the above error by following these steps:
Right click on project->Build path->Configure build path->source tab
then search tab search under your project src/main/java
and change "contains test sources" from No to Yes
and apply the changes
This might be a silly question, but I need to know. I'll delete it if it's too silly to answer.
In a maven project in IntelliJ, I have the following structure:
procedure
e2e
cucumber (same level as common)
src
test
java
e2e
support
File: ScenarioState.java
package e2e.support
common (same level as cucumber)
src
main
java
common
testdata
File: Case.java
package common.testdata
Is there any way to import the package e2e.support (where ScenarioState.java resides) into the file Case.java in the common.testdata package?
I've been playing around with maven imports, dependencies etc., but I haven't found a way to do it. I might have to redesign some classes to get around it, but that would impact other parts of the project and I'd like to avoid it if possible.
If you really want to do that (and I would strongly recommend to either leave the project alone or restructure it first), define an additional source directory as in
How to add an extra source directory for maven to compile and include in the build jar?
But beware that a project like this will haunt you till the end of time.
One could have in the common's pom.xml a dependency to cucumber with <type>test-jar</type>.
However this violates the concept of src/main for the final product, and src/test for the unit-tests (not incorporated in the product, separate test classes).
(In src/test there can be other classes, so maybe easiest would be for common to have a src/test instead.)
If ScenarioState has nothing to do in src/main, one could place it in a more low-level library cucumberbase in src/main. And make a dependency in cucumber to cucumberbase with <scope>test</scope>. In <common> a normal dependency to cucumberbase.
Keep this main-test separation as otherwise other developers risk insanity.
It seems that in Java 9 it is not allowed to have so-called Split Packages, i.e. the same package being defined in two different modules. This causes a problem with my migration process: The (Gradle) project contains a Jar file that is called bootstrap.jar, with a structure like this:
bootstrap.jar
- com
- example
- Foo.class
- Bar.class
- Baz.class
The src directory contains a class com.example.Bar that depends on Foo as well as a module definition, for com.example. The bootstrap.jar file does not contain a module info, as it was compiled before Java 9, so it uses an automatic module called bootstrap. The problem is that now the package com.example is defined in both modules, com.example and bootstrap.
The reason there is this bootstrap.jar file, to begin with, is as follows:
The src/com/example folder actually contains Bar.java, Baz.java and another file, Foo.dyvil. The latter is written in a JVM-based programming language. So the dependency chain looks like this:
Bar.java -> Foo.dyvil -> Baz.java
During the build process, it gets compiled to Foo.class, which gets placed in a new Jar file that later replaces bootstrap.jar. The reason all these files are placed is that both the Java and Dyvil compiler cannot process the other languages files, so they require some access to the compiled classes from the previous build. So that is why there is bootstrap.jar.
Now for the actual problem: Since split packages are disallowed in Java 9, is there any way to achieve "split builds" using "bootstrap" jar files as described and used in my project? Or is there any other approach?
Though the long-term solution to this is resolving such packages to exist in a single module and then modularising the code.
As a temporary solution, you can make use of the option:-
--patch-module <module>=<file>(<pathsep><file>)*
as in your case
--patch-module com.example=bootstrap.jar
Do keep in mind though, the --patch-module option is intended only for testing and debugging. Its use in production settings is strongly discouraged.
I am using IntelliJ to write some integration tests.
Project Structure:
/src
/main
/java
/com.myCompany
/dir
/email
/test
/com
Over time, I will be writing unit, integration, and performance tests. However, I’m confused about how I should structure my directories for testing. I also don’t understand how package naming relates to testing. For instance, I’ve created a basic test that looks like the following:
package com.myCompany.dir.email;
import junit.framework.TestCase;
import org.junit.Test;
public class EmailTest extends TestCase {
private final String username = “[testAccount]”;
private final String password = “[testPassword]”;
#Test
public void thisAlwaysPasses() {
assertTrue(true);
}
}
Unfortunately, I can’t even get that test to run. I get errors ranging from:
Error running All unit tests: Package not found in directory
to
No tests found.
Any insights are much appreciated.
It is a good idea to have your tests packages mirror the package structure of your classes under test. In your concrete case it should look like this:
/src
/main
/java
/com
/myCompany
/dir
/email
MyClass.java
/test
/java
/com
/myCompany
/dir
/email
MyClassTest.java
Regarding your part of the question about Unit-, Integration- and Performance-Tests. We usually follow either one of the following approaches (it kinda depends on the project size):
Create completely separate projects for Integration-Tests (and Performance Tests). In there you place your Tests within an identical package hierachy.
Simply place your Integration-Tests (and Performance Tests) in the same package as your Unit-Tests, but give them some common suffix (e.g. MyClassIntegrationTest.java)
there's no need to extend TestCase--the rest of your code is probably fine.
assuming you're using Maven directory structures (you appear to be), be sure you created a folder structure for tests which looks like: src/test/java/com/myCompany/dir/email--your class needs to be in a folder which matches its package name,
the extra quote in "[test"Password"]; -- you need to remove or escape it.
I'm guessing that #1 is the cause of the exception you're currently seeing.
I am a long time user of Eclipse but a novice when it comes to JUnit. I have lots of java projects and I want to start writing test cases around the methods in those projects. I'm just wondering the best way to set up the Eclipse environment for this purpose. Let's assume I have a typical project with a typical src directory in a specified package. How do I attach test cases to that project. Some concerns:
1. I don't want the test cases to be part of any build that I create on the project.
2. I want to refer to the clases in the test-suite.
Do I set up a separate test directory under the package I want to test? Do I have a separate test package? What is the best way to do this?
It's pretty dead simple:
Drag or otherwise place the JUnit jar file into your lib folder, then
modify your projects build settings to include it.
Create another source folder under your project called 'test'
Create your test packages underneath the 'test' source folder. Best
practice is to mimic the package names of your application.
Create your test classes inside of the test packages. Best practices
is to mimic your application classes that require testing, but append
Test at the end of the name. So for example in your main application
you might have a myapp.service.PrintService and as a corresponding
test you would have myapp.service.PrintServiceTest
Extend each test class from junit.framework.TestCase
Run your test classes using TestRunner.
When you build your application's deployment bundle just exclude the 'test' source folder. Now, if you want really drop dead easy test integration then use Maven to setup your project. It bakes in all the best practices for you right off the bat.
The best (or at least the most common) way to organize the test code it is to have a separate source folder for the test code, thus keeping it nicely separated. In eclipse, you can add source folders under "Build Path" in the project's properties.
However, it is also a good idea to keep your test classes in the same packages as the classes to be tested (i.e. have the same package hierarchy in the test source folder). This allows you test code to call package private and protected methods, making it much easier to test internal behaviour that should not be exposed in the public API.
A simple solution would be to create another source directory specifically for test-related classes. For example, if your main classes live in $PROJECT_ROOT/src, you can put your test-related classes in $PROJECT_ROOT/src-test. I don't have Eclipse handy, but I know that you can modify the $PROJECT_ROOT/.classpath file (it's XML) to include this new directory:
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src-test"/> <!-- ADD THIS ONE -->
...
</classpath>
Now, all your test classes will see the main classes, but they won't be included in your build. I typically make sure that the test class lives in the same package as the class it's testing. That way, any protected members can be accessed from the test code.