Skip to content

Initial setup

Vladimir Turov edited this page Aug 3, 2021 · 24 revisions

First time

You are not limited to using the EduTools plugin when creating tests for a project (you can just create a regular IntelliJ IDEA project), but with the EduTools plugin, it may be more convenient.

To create a project with the EduTools plugin, you need to download IntelliJ IDEA Edu. This version already contains the installed version of the EduTools plugin. If you already have a regular installation of IntelliJ IDEA installed, you can download the plugin from Marketplace.

After that, make sure you have enabled EduTools' project creating features:

  1. Click Help -> Enable Course Creator Features
  2. Click Ctrl + Shift + A -> Experimental features -> check the box next to edu.course.hyperskill

Every time

To create a project, you need to click File -> Learn and Teach -> Create New Hyperskill Course

Set the title and click Create. It does not matter if you choose Java or Kotlin since you'll later change build.gradle file for the appropriate language.

This is how your project should look like for now. Please, don't touch .yaml files - they are internal for the EduTools plugin.

Next, you need to delete lesson1. You should end up with a single file build.gradle. Replace the contents of this file with what was given below (in File templates section).

Then, you should create a so-called Framework Lesson and give it a name like a project name. For this, you need to create a new Lesson and choose Framework lesson in the dialog.

Then, you should create a new Task inside this Framework Lesson and give it the name stage1. The task type should be Edu.

Then remove src/Task.java and test/Tests.java, create package src/tictactoe, create file src/tictactoe/Main.java, create file test/TicTacToeTest.java replace the contents of these files with what was provided below (in File templates section). Notice, that you need to name folder and file appropriately your project theme, don't stick to Tic-Tac-Toe. This is just an example. You should end up with this configuration:

To create tests for the second stage, click on Framework Lesson named Tic-Tac-Toe and add a new Task. Name it stage2. Your result should look like the following:

If you see (excluded) near your files, please right-click on this file and click Course Creator -> Include into Task to include this file into the project.

Also, if you don't want some files to be seen by a user, you can hide them. It is especially useful when you're including tests into the project, and they are added as visible files by default, so you should hide them as well. In EduTools, hidden files are displayed in gray, and visible files are displayed in black.

You created an initial setup and ready to write tests!

After you finished creating your project, you need to upload it to Stepik. To do this, please click on a project name (the one with 4 squares, not to the one with a book), and click Course Creator -> Upload Hyperskill Lesson to Stepik.

File templates

To build a project, we use gralde. You need to use Gradle version 5 or newer (for Java 13, 14, 15 you should use Gradle 6.3+) and at least Java 8. A typical project with several stages with Java/Kotlin/Scala tests looks like this:

Idea_project_folder
    .idea
        --Idea internal files--
    build.gradle
    settings.gradle
    Project_name
    |   stage1
    |   |   src
    |   |   |   user_package
    |   |   |       --user files--
    |   |   test
    |   |       --test files--
    |   stage2
    |   |   src
    |   |   |   user_package
    |   |   |       --user files--
    |   |   test
    |   |       --test files--
    |   ...
    |   stageN
    |   |   src
    |   |   |   user_package
    |   |   |       --user files--
    |   |   test
    |   |       --test files--

As you can see, the project is divided into stages. Each stage is a separate Gradle submodule and does not overlap with other stages in any way. The user_package package is intended for the user to write his code to the project. The test folder is intended for writing tests to the project stage.

So, the initial setup for writing tests for a Java/Kotlin/Scala project is as follows (let's say you're writing tests for the Tic-Tac-Toe project):

Idea_project
    build.gradle
    settings.gradle
    Tic-Tac-Toe
    |   stage1
    |   |   src
    |   |   |   tictactoe
    |   |   |       Main.java / Main.kt / Main.scala
    |   |   test
    |   |       TicTacToeTest.java

The file Main.* can contain some initial code for the student. They'll see it the first time they open the project. Usually, this file looks like this for a student when opening a project for the first time:

Main.java:

package tictactoe;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Main.kt

package tictactoe

fun main() {
    println("Hello World!")
}

Main.scala

package tictactoe

object Main extends App {
    println("Hello, World!")
}

You shall implement the project stage in this file. Since you will have to check whether your tests work or not.

Below is an initial example of the TicTacToeTest.java file. Noice, that you don't need the user's class at all - the library will find the main method across all user's classes automatically.

import org.hyperskill.hstest.dynamic.DynamicTest;
import org.hyperskill.hstest.stage.StageTest;
import org.hyperskill.hstest.testcase.CheckResult;

public class TicTacToeTest extends StageTest {
    @DynamicTest
    CheckResult test() {
        return CheckResult.correct();
    }
}

Java, Kotlin, Scala projects can be tested using tests written in Java.

If you want to write tests in Kotlin, you can use the following template:

import org.hyperskill.hstest.dynamic.DynamicTest
import org.hyperskill.hstest.stage.StageTest
import org.hyperskill.hstest.testcase.CheckResult

class TicTacToeTest : StageTest<Any>() {
    @DynamicTest
    fun test(): CheckResult {
        return CheckResult.correct()
    }
}

Scala tests are not supported, you should write tests in Java to test Scala program.

Below are the build.gradle and settings.gradle files that you should use.

build.gradle for Java projects:

buildscript {
    repositories {
        mavenCentral()
    }
}

subprojects {
    apply plugin: 'application'
    apply plugin: 'java'

    sourceCompatibility = 11

    repositories {
        mavenCentral()
        maven { url "https://jitpack.io" }
    }

    dependencies {
        testImplementation 'com.github.hyperskill:hs-test:release-SNAPSHOT'
    }

    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }

    sourceSets {
        main.java.srcDir 'src'
        test.java.srcDir 'test'
    }

    test {
        systemProperty "file.encoding", "utf-8"
        outputs.upToDateWhen { false }
    }

    compileJava.options.encoding = 'utf-8'
    tasks.withType(JavaCompile) {
        options.encoding = 'utf-8'
    }
}

wrapper {
    gradleVersion = '7.1.1'
}

build.gradle for Kotlin projects

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
    }
}

subprojects {
    apply plugin: 'application'
    apply plugin: 'java'
    apply plugin: 'kotlin'

    sourceCompatibility = 1.8

    repositories {
        mavenCentral()
        maven { url "https://jitpack.io" }
    }

    dependencies {
        testImplementation 'com.github.hyperskill:hs-test:release-SNAPSHOT'
    }

    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }

    sourceSets {
        main.java.srcDir 'src'
        test.java.srcDir 'test'
    }

    test {
        systemProperty "file.encoding", "utf-8"
        outputs.upToDateWhen { false }
    }

    compileJava.options.encoding = 'utf-8'
    tasks.withType(JavaCompile) {
        options.encoding = 'utf-8'
    }
}

wrapper {
    gradleVersion = '7.1.1'
}

build.gradle for Scala projects

buildscript {
    repositories {
        mavenCentral()
    }
}

subprojects {
    apply plugin: 'application'
    apply plugin: 'scala'
    apply plugin: 'java'

    repositories {
        mavenCentral()
        maven { url "https://jitpack.io" }
    }

    dependencies {
        implementation 'org.scala-lang:scala-library:2.12.7'
        testImplementation 'com.github.hyperskill:hs-test:release-SNAPSHOT'
    }

    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }

    sourceSets {
        main.java.srcDir 'src'
        main.scala.srcDir 'src'
        test.java.srcDir 'test'
        test.scala.srcDir 'test'
    }

    test {
        systemProperty "file.encoding", "utf-8"
        outputs.upToDateWhen { false }
    }

    compileJava.options.encoding = 'utf-8'
    tasks.withType(JavaCompile) {
        options.encoding = 'utf-8'
        sourceCompatibility = 11
    }
    tasks.withType(ScalaCompile) {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
}

wrapper {
    gradleVersion = '7.1.1'
}

settings.gradle:

static String sanitizeName(String name) {
    return name.replaceAll("[ /\\\\:<>\"?*|]", "_")
}

rootProject.projectDir.eachDirRecurse {
    if (!isTaskDir(it) || it.path.contains(".idea")) {
        return
    }
    def taskRelativePath = rootDir.toPath().relativize(it.toPath())
    def parts = []
    for (name in taskRelativePath) {
        parts.add(sanitizeName(name.toString()))
    }
    def moduleName =  parts.join("-")
    include "$moduleName"
    project(":$moduleName").projectDir = it
}

def isTaskDir(File dir) {
    return new File(dir, "src").exists()
}

Notice dependency testImplementation 'com.github.hyperskill:hs-test:release-SNAPSHOT' - it's this hs-test library. This dependency points to the latest commit of the release branch so the EduTools plugin will download relevant version of the library every time a user starts a project. The part configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } will ensure that Gradle will update the library on the user side after every commit immediately. If you want to use the latest features (or you're just trying to fix a bug) use master branch. But keep in mind, that every project on Hyperskill uses release branch.