Tests in Gradle sub-project cannot see Kotlin internal visibility - gradle

Kotlin internal visibility is scoped to the "module" including the helpful statement that it may be:
a Gradle source set (with the exception that the test source set can access the internal declarations of main)
... so you can unit-test internal methods.
My Gradle build holds performance tests in a sub-project. How can I make those also "see" internal items of the parent?
The standard import doesn't do this
dependencies {
compile project(':myParentName')`
}
If it's impossible from a sub-project, how can a custom source-set (i.e. not test) in the main project have the same exception?
PS. It is quite common to see JMH performance tests put into a sub-project to keep configuration from polluting from the main build.gradle. This doesnt mean they are only tests of public interfaces (see the M in JMH).

Related

maven test dependencies of dependencies

I have a large project and i want to add an integration tests module which will depend on every thing and validate interaction between modules.
The issue is that during the test I'm missing the dependency classes
module A uses module B
I have a test on module A testing something that uses module B, and I'm getting an error stating it can't find classes in module B.
I tried surefire but there is no difference.
I know I can and I should mock the classes in B which aren't part of the test but I want a full test that will test everything.
As official Maven documentation declares test scope is not transitive. You need to declare required dependencies explicitly in the pom file(s).
You cannot change this behaviour, but there is usually no need to change this behaviour.
If you want to write a library that is used for testing, then this library should have compile dependencies, but when you use it, declare it with scope test.

Gradle configurations integration

I've found this code at work in build.gradle
configurations {
all {
resolutionStrategy {
cacheDynamicVersionsFor 0, 'seconds'
}
}
integration
}
I can't find anywhere what integration keyword stands for. Can you explain to me?
In this example, the build is declaring a new configuration called integration. And a configuration can for the most part be thought of as a bucket or collection of dependencies. If a plugin or the Gradle core new about a particular configuration, there would usually be no need to declare it as it would already exist to begin with.
Let's assume that 'integration' is short for 'integration test'. Then what's going on here is that your build is saying: "Hey, I need a bunch of dependencies for running my integration test, but I don't want to pollute the classpath for the other kinds of runtime environments. So please make me a bucket of dependencies to isolate the integration test".
Later in the build file (which you didn't show), you will then find a dependencies block where the integration configuration is populated with the modules needed for running the test. And lastly, some task that actually uses it, presumably for setting the classpath.
It could be used for a number of other things of cause. But whatever it is, it is probably something custom and you could rename it (and all references to it) to 'aCollectionOfAwesomeDependenciesUsedForRunningOurIntegrationTest' if you like.

Gradle kotlin how to call function defined in parent?

When working with gradle multimodule project, is it possible to define functions in parent project but use them in submodules build.gradle.kts?
Note i do not need untyped tasks registered and called with strings... I want actual typesafe code to be shared to submodules.
Ideally without creating a plugin or using buildSrc.
Whats the most to the point way to share a class from parents build.gradle.kts to all submodules?
NOTE : this is not the same as sharing closure trough ext... you loose type safety, what i ask for is Type safety on submodule side.
I'm thinking that there is no way. When a Kotlin build script gets compiled, it will end up as a class called Build_gradle in the default package (i.e. empty package) that extends CompiledKotlinBuildScript. Any class that is defined within a script becomes a public nested class in its corresponding Build_gradle. When the subproject build script gets compiled, it has no access to the classpath that contains the parent projects build script. This makes sense, as there would be multiple Build_gradle files in the same (default) package.
I'd go for buildSrc, to solve the problem, but I'm speculating that what you also wanted was some sort of nice separation of concerns in a multimodule project, not having unrelated projects knowing about what others need to communicate. What you could do to minimize the exposure is to only keep the API (interfaces, data classes) in buildSrc and have a script plugin in a parent project provide the implementation.

Why isn't JUnit's assertTrue being resolved?

I have a project that follows the standard Maven structure:
project
src
main
java
test
java
In some classes, assertTrue is able to be resolved, and in others it cannot be resolved.
I took the static import from the class (in the src/java/test directory) that is resolving and pasted it into the class that can't resolve assertTrue (in the src/java/main directory) and that didn't resolve it.
So using import static org.junit.Assert.assertTrue; doesn't work.
Using Assert.assertTrue doesn't work either.
Edit:
One thing that I didn't make clear in the initial post is that this isn't a standard Java project with unit tests. The project is the integration test framework for another Java program. So all the code within this project exists to test the functionality of another program using the external REST API. Hence why I had a Junit assertion outside the test folder. Granted there may still be an opportunity to clean that up.
So the issue was in my build.gradle file that I had specified the junit dependency as a testCompile dependency. Meaning that it would only be apply to classes within the src/test directory. So to resolve my issue, I changed the build.gradle to use compile('junit:junit:4.12').
I could have also moved the file that wasn't resolving into the src/test directory, but the file didn't logically belong there.

Understanding Maven scoping better

I have been struggling to figure out what's the use of scoping that is provided by Maven
as mentioned here.
Why should you not always have compile time scoping? Real life examples would be really appreciated.
The compile scoped dependencies are only used during compilation.
The test scoped ones -- only during tests. Say you have tests using junit, or easymock. You obviously do not want your final artifact to have a dependency on them, but would like to be able to just depend on these libraries while running your tests.
Those dependencies which are marked provided are expected to be on your classpath when you're running the produced artifact. For example: you have a webapp and you have a dependency on the servlet library. Obviously, you should not package it inside your WAR file, as the webapp container will already have it and a conflict may occur.
One of the reasons to have different scopes for dependencies is that different parts of the build can depend on different dependencies. For example, if you are only compiling your code and not executing any tests, then there is no point in having Maven downloading your test dependencies (if they're not already present in your local repository, of course). The other reason is that not all dependencies need to be placed in your final artifact (whether it's an assembly, or WAR file), as some of the dependencies are only used during the build and testing phases.
compile
Will copy these jar files into prepared War file.
Ex: hibernate-core.jar need to have in our prepared War.
provided
These jars will be considered only at complie time and test time
Ex:
servlet.jar will be provided by deployed server, so no need to provide from our prepared War file.
test
These jars are only required for running test classes.
Ex: Junit.jar will be required only for running Junit test classes, no need to deploy these.
Scopes are quite well explained in here:
https://maven.apache.org/pom.html#Dependencies
As a reference, I copied the paragraph:
scope: This element refers to the classpath of the task at hand
(compiling and runtime, testing, etc.) as well as how to limit the
transitivity of a dependency. There are five scopes available:
compile
- this is the default scope, used if none is specified. Compile dependencies are available in all classpaths. Furthermore, those
dependencies are propagated to dependent projects.
provided - this is
much like compile, but indicates you expect the JDK or a container to
provide it at runtime. It is only available on the compilation and
test classpath, and is not transitive.
runtime - this scope indicates
that the dependency is not required for compilation, but is for
execution. It is in the runtime and test classpaths, but not the
compile classpath.
test - this scope indicates that the dependency is
not required for normal use of the application, and is only available
for the test compilation and execution phases.
system - this scope is
similar to provided except that you have to provide the JAR which
contains it explicitly. The artifact is always available and is not
looked up in a repository.
there are a couple of reasons that you might not want to have all dependencies to be default compile scope
reduce the size of final artifact(jar,war...) by indicating different scope.
when you have a multiple-modules project, you have ability to let each module have it's own version of dependency
avoid class version collision by provided scope, for instance if you are going deploy a war file to weblogic server, you need to get rid of some javax jars, like javax.servlet, javax.xml.parsers, JPA jars and etc. otherwise you might end up with class collision error.

Resources