A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://plugins.jetbrains.com/docs/intellij/integration-tests-intro.html below:

Introduction to Integration Tests | IntelliJ Platform Plugin SDK

Introduction to Integration Tests

This page is part of the Integration Tests tutorial.

Adding dependencies

Integration testing framework consists of two main components:

The Starter framework exclusively supports JUnit 5, as it leverages JUnit 5's extensions and specialized listeners that aren't available in JUnit 4.

To create a new task - integrationTest, define new test source roots - integrationTest, and add required dependencies, update the build.gradle.kts file:

dependencies { intellijPlatform { //... testFramework(TestFrameworkType.Starter) } sourceSets { create("integrationTest") { compileClasspath += sourceSets.main.get().output runtimeClasspath += sourceSets.main.get().output } } val integrationTestImplementation by configurations.getting { extendsFrom(configurations.testImplementation.get()) } dependencies { integrationTestImplementation("org.junit.jupiter:junit-jupiter:5.7.1") integrationTestImplementation("org.kodein.di:kodein-di-jvm:7.20.2") integrationTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1") } val integrationTest = task<Test>("integrationTest") { val integrationTestSourceSet = sourceSets.getByName("integrationTest") testClassesDirs = integrationTestSourceSet.output.classesDirs classpath = integrationTestSourceSet.runtimeClasspath systemProperty("path.to.build.plugin", tasks.prepareSandbox.get().pluginDirectory.get().asFile) useJUnitPlatform() dependsOn(tasks.prepareSandbox) }

The following dependencies are required:

This configuration does the following:

For more details about configuring integration tests, please refer to Gradle docs.

Note: Driver and UI components are in the experimental state and subject to API changes.

Creating the First Integration Test

Now that the configuration is complete, it's time to write the first integration test, which will:

Create a new Kotlin file in src/integrationTest/kotlin with the following code:

class PluginTest { @Test fun simpleTestWithoutProject() { Starter.newContext( testName = "testExample", TestCase(IdeProductProvider.IC, projectInfo = NoProject) .withVersion("2024.3") ).apply { val pathToPlugin = System.getProperty("path.to.build.plugin") PluginConfigurator(this).installPluginFromFolder(File(pathToPlugin)) }.runIdeWithDriver().useDriverAndCloseIde { } } }

Let's break down each part of the test:

1. Context Creation

Starter.newContext( testName = "testExample", TestCase(IdeProductProvider.IC, projectInfo = NoProject ).withVersion("2024.3"))

The Context object stores IDE runtime configuration:

The testName parameter defines the folder name for test artifacts, which is useful when running multiple IDE instances in a single test. The test case uses IntelliJ IDEA Community Edition version 2024.3, and starts the IDE without any project, so the welcome screen will be shown.

2. Plugin Installation

.apply { val pathToPlugin = System.getProperty("path.to.build.plugin") PluginConfigurator(this).installPluginFromFolder(File(pathToPlugin)) }

This step configures plugin installation using the plugin path defined in the Gradle configuration with the path.to.build.plugin system property.

PluginConfigurator can install plugins from local paths or Marketplace.

3. IDE Life Cycle Management

.runIdeWithDriver().useDriverAndCloseIde { }

These two methods:

The empty lambda is used for IDE interactions (useDriverAndCloseIde).

When the test is run for the first time, it may take longer than expected since it needs to download the IDE. Subsequent runs will be faster, using the cached IDE version.

Understanding the Test Architecture

The test can now be run and it should pass.

Integration tests operate across two separate processes:

This dual-process architecture explains several key aspects of integration testing:

Opening Projects in Tests

While starting the IDE with an empty project is useful, often it is required to use actual projects to verify real-world scenarios. Let's modify the test to open a project.

The framework supports several ways to specify test projects:

The following example shows how to open a GitHub project:

@Test fun simpleTest() { Starter.newContext( "testExample", TestCase( IdeProductProvider.IC, GitHubProject.fromGithub( branchName = "master", repoRelativeUrl = "JetBrains/ij-perf-report-aggregator" ) ).withVersion("2024.2") ).apply { val pathToPlugin = System.getProperty("path.to.build.plugin") PluginConfigurator(this).installPluginFromFolder(File(pathToPlugin)) }.runIdeWithDriver().useDriverAndCloseIde { waitForIndicators(5.minutes) } }

While simple, this test verifies a critical aspect: the plugin doesn't interfere with IDE startup.

waitForIndicators inside the lambda ensures that the test waits till all indicators are gone before exiting the IDE.

Catching Exceptions from IDE

The test has one critical limitation: it won't detect exceptions or freezes occurring within the IDE process. Let's understand why and how to fix this.

Due to the two-process architecture:

TeamCity reporting is used by default, falling back to NoCIServer for other environments. However, this can be customized by using Kodein Dependency Injection.

The following example shows how to make tests fail when IDE exceptions occur:

init { di = DI { extend(di) bindSingleton<CIServer>(overrides = true) { object : CIServer by NoCIServer { override fun reportTestFailure( testName: String, message: String, details: String, linkToLogs: String? ) { fail { "$testName fails: $message. \n$details" } } } } } }

The code above:

This extensibility pattern can be applied to customize other aspects of the Starter framework as needed.

Complete Example

Here's the complete test implementation that forms the foundation for future plugin testing:

class PluginTest { init { di = DI { extend(di) bindSingleton<CIServer>(overrides = true) { object : CIServer by NoCIServer { override fun reportTestFailure( testName: String, message: String, details: String, linkToLogs: String? ) { fail { "$testName fails: $message. \n$details" } } } } } } @Test fun simpleTest() { val result = Starter.newContext( "testExample", TestCase( IdeProductProvider.IC, GitHubProject.fromGithub( branchName = "master", repoRelativeUrl = "JetBrains/ij-perf-report-aggregator" ) ).withVersion("2024.2") ).apply { val pathToPlugin = System.getProperty("path.to.build.plugin") PluginConfigurator(this).installPluginFromFolder(File(pathToPlugin)) }.runIdeWithDriver().useDriverAndCloseIde { waitForIndicators(5.minutes) } } }

This test provides a robust foundation for more elaborate tests by:

25 March 2025


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4