The Unit Testing library for Vaadin.
When building apps with Vaadin Flow, your app manipulates Vaadin components
server-side, while the browser is just a mere "reflection" of
the server-side state. For example, setting the Button
's caption to "Foo" updates the Button
's
state server-side; Vaadin Flow then automatically applies the change in the browser-side <vaadin-button>
element.
This happens automatically, behind-the-scenes; this is tested by the Vaadin company and doesn't need to be
tested by your app. Therefore, to test your app, you can leave out the "unimportant" browser part: you
want your tests to focus on the server-side where your logic resides.
Karibu-Testing gives you the ability to call UI.getCurrent()
straight from your JUnit
test methods, and receive a
meaningful result in the process. You can call UI.navigate()
to navigate around in your app;
you can instantiate your components and views directly from your JUnit test methods.
In order to do so, Karibu-Testing mocks CurrentRequest
, VaadinSession
and others in your
currently running JVM (in which your JUnit tests run).
Karibu-Testing only runs in JVM and only tests server-side code. There is no browser running
and no JavaScript code running, which means that there is no communication between the browser and the server,
which means that you don't even need to run the servlet container. You simply create new instance
of your Vaadin form, modify the field values directly, then simulate a click to the "Save" button
and see the binder validations running. You can even call UI.navigate()
to
navigate to a view; the navigation is handled completely server-side and adds components to UI.getCurrent()
.
You then assert on the contents of UI.getCurrent()
to verify that your code ran properly.
In short, Karibu-Testing is here to perform:
UI.getCurrent()
, bypassing browser and the JavaScript->Server bridge completely.
You directly call methods on your server-side View classes and on the server-side Java Vaadin components.If you like the library, please star it. The more stars, the more popularity and more maintainenance the library will receive.
Check out a 30 second video of live coding with Karibu-Testing to get a taste on how simple this library is.
The library supports Kotlin, Java and Groovy (Groovy support for Vaadin 14+ only).
The Vaadin UI Unit-Testing idea, pioneered by Karibu-Testing, proved useful for many Vaadin users. Vaadin recognized the effort and is adding official support for UI unit-testing into TestBench. The Vaadin UI Unit-Testing is now available in alpha builds of TestBench for Vaadin 23.1.1; stable version will require at least Vaadin 23.2 (maybe higher).
At the moment the Vaadin API is being prototyped and is not finalized. The Vaadin API will most probably look a bit differently than Karibu-Testing API though:
LocatorJ
and others)
to make Karibu accessible in Java. While we do offer full support for Java (and a bit limited support for Groovy),
we will stay with the static methods solution for Java.At the moment Karibu-Testing classes are included in the Vaadin UI Unit-Testing library (as an implementation detail). However, this can change at any time.
The development of both products will now happen independently. If the Vaadin guys have a lovely idea, please open a feature request for Karibu so that we can steal those ideas :-D (Did you know that greatest artists steal?)
Important: The development of Karibu-Testing will continue as usual; we will continue supporting both Vaadin 14 and 23, both Kotlin, Groovy and Java, and we will continue designing the API via the "extension functions" mechanism.
>>>See The main Karibu-Testing documentation for Vaadin 14+ <<<. Karibu-Testing is compatible with any Vaadin 14+ version (14, 15, 16, 17, 18, 19, 20, 21, 22, 23 etc).
>>>See The main Karibu-Testing documentation for Vaadin 8 <<<. Karibu-Testing is compatible with any Vaadin 8.x version.
Advantages over the traditional testing with Selenium/TestBench:
@BeforeClass
and
stop the server in your @AfterClass
. There is no need to use Maven's Integration plugin
to start the server in the background (and then remember to kill it afterwards, otherwise all future CI tests
will fail to start the server since it's already running).With this technique you can run 600 UI tests in 7 seconds, as opposing to 1-2 hours with Selenium-based approach. Because of the speed, you can let the UI tests run after every commit by your continuous integration server.
Since we're bypassing the browser and talking to Vaadin server API directly, you don't even need to start the servlet container - you can just add the server jars onto testing classpath and call Vaadin server API which will in turn invoke your server logic.
A 15-minute video explains everything behind the browserless testing technique.
The Karibu-Testing library is Standalone and Fully Supports Java and Groovy.
Even though the Karibu-Testing is endorsed by Vaadin-on-Kotlin, the Karibu-Testing does not really depend on any other technology than Vaadin. You don't have to use Vaadin-on-Kotlin nor Karibu-DSL to use Karibu-Testing. You don't even need to write your app nor your tests in Kotlin, since the library provides native API for Kotlin, Java and Groovy.
You can therefore plug this library in into your Java+Vaadin-based project as a test dependency, and write the test code in Java, Kotlin or Groovy, whichever suits you more.
Karibu-Testing is published on Maven Central, so it's very easy to add as a Maven dependency.
The library is mature and stable since 2020. It has been extensively tested and employed in numerous real-world projects. Small features are being added infrequently, and compatibility with all latest Vaadin versions is checked on every commit.
A list of a very simple example projects that employ Karibu Testing:
v19
branch for Vaadin 19).Karibu-Testing is designed to bypass browser and the servlet container. It's a double-edged sword: while this provides insane speed, it also sets limits what you can do with Karibu-Testing:
Here are a few tips on how to "start" your app in the JUnit JVM:
MockVaadin.setup { MyUI() }
before every test, and MockVaadin.tearDown()
after every test. That will
instantiate your UI along with all necessary Vaadin environment.VaadinOnKotlin.dataSourceConfig
and then init vok: VaadinOnKotlin.init()
before all tests. Or even better,
since you typically do this in a ServletContextListener
such as the Bootstrap
class, simply call that: Bootstrap().contextInitialized(null)
. Then, when the app is bootstrapped,
you can proceed to setting up your UI by calling MockVaadin.setup { MyUI() }
before every test, and MockVaadin.tearDown()
after every test.ServletContextListener
which you have in your app, before all tests are executed.
Then, when the app is bootstrapped,
you can proceed to setting up your UI by calling MockVaadin.setup { MyUI() }
before every test, and MockVaadin.tearDown()
after every test.MockVaadin.setup { beanFactory!!.getBean(MainUI::class.java) }
before every test, and MockVaadin.tearDown()
after every test. Please see the karibu-testing-spring example project
for more details.This project also offers a mock/fake servlet API implementation, see mock-servlet-environment for more details.
Q: I'm getting java.lang.IllegalStateException: UI.getCurrent() must not be null
or no VaadinSession bound to current thread
.
A: You probably forgot to call MockVaadin.setup()
before the test. Just call MockVaadin.setup()
e.g. from your @Before
-annotated method if you're using JUnit.
Alternatively it could be that Spring is instantiating Vaadin component eagerly
when the ApplicationContext is constructed. One workaround is to mark
Vaadin components with @Lazy
so that they are instantiated lazily.
Q: I'm getting RouteNotFoundError
/NotFoundException
instead of my views (Vaadin 14+)
A: The @Route
-annotated view classes have not been discovered and registered.
Please discover the routes via new Routes().autoDiscoverViews("com.example.yourpackage")
(make sure to use the correct Java package where all of your views are placed)
then call MockVaadin.setup(routes)
.
Also when migrating from Karibu-Testing 1.1 to 1.2.x and you're using a custom VaadinServlet
,
please make sure to call routes.register(service.context as VaadinServletContext)
from the
createServletService()
method, as shown in Issue #60.
Q: Can I integrate CDI (e.g. weld?)
A: You can get inspiration here.
Q: Performance speed-up tips?
@BeforeClass
-annotated method), then store the Routes
instance into a static field and reuse it for every call to MockVaadin.setup(routes)
.new Routes().autoDiscoverViews("")
is slower than
new Routes().autoDiscoverViews("com.example.yourpackage")
Routes.skipPwaInit
should be true
which is also the default value).User
instance into your session directly (this of course
pretty much depends on how security is handled in your app).Licensed under Apache 2.0
Copyright 2017-2018 Martin Vysny
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
See Contributing.