Skip to content

Commit

Permalink
Readme UltronTest
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-tiurin committed Nov 27, 2024
1 parent 4fd34c6 commit 782bc81
Show file tree
Hide file tree
Showing 16 changed files with 429 additions and 172 deletions.
72 changes: 63 additions & 9 deletions composeApp/src/commonTest/kotlin/UltronTestFlowTest.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,77 @@

import com.atiurin.ultron.annotations.ExperimentalUltronApi
import com.atiurin.ultron.core.test.UltronTest
import com.atiurin.ultron.log.UltronLog
import kotlin.test.Test
import kotlin.test.assertTrue

class UltronTestFlowTest : UltronTest() {
companion object {
var order = 0
var beforeAllTestCounter = -1
var commonBeforeOrder = -1
var commonAfterOrder = -1
var afterOrder = -1

}

class UltronTestFlowTest: UltronTest() {
override val beforeAllTests = {}
@OptIn(ExperimentalUltronApi::class)
override val beforeFirstTests = {
beforeAllTestCounter = order
UltronLog.info("Before Class")
}

override val afterAllTests = {}
override val beforeTest = {
commonBeforeOrder = order
order++
UltronLog.info("Before test common")
}
override val afterTest = {
commonAfterOrder = order
order++
assertTrue(afterOrder < commonAfterOrder, message = "CommonAfter block should run after 'after' test block")
UltronLog.info("After test common")
}

override val afterTest = {}
@Test
fun someTest1() = test {
var beforeOrder = -1
var goOrder = -1
order++
before {
beforeOrder = order
order++
UltronLog.info("Before TestMethod 1")
}.go {
goOrder = order
order++
UltronLog.info("Run TestMethod 1")
}.after {
afterOrder = order
order++
assertTrue(beforeAllTestCounter == 0, message = "beforeAllTests block should run before all test")
assertTrue(beforeAllTestCounter < commonBeforeOrder, message = "beforeAllTests block should run before commonBefore block")
assertTrue(commonBeforeOrder < beforeOrder, message = "beforeOrder block should run after commonBefore block")
assertTrue(beforeOrder < goOrder, message = "Before block should run before 'go'")
assertTrue(goOrder < afterOrder, message = "After block should run after 'go'")
}
}

@Test
fun someTest() = test {
fun someTest2() = test(suppressCommonBefore = true) {
before {
UltronLog.info("Before TestMethod")
UltronLog.info("Before TestMethod 2")
}.after {
UltronLog.info("Before TestMethod")
UltronLog.info("After TestMethod 2")
}.go {
UltronLog.info("Run TestMethod")
assertTrue(beforeAllTestCounter == 0, message = "beforeAllTests block should run only once")
UltronLog.info("Run TestMethod 2")
}
UltronLog.info("UltronTest test")
}

@Test
fun simpleTest() = test {
assertTrue(beforeAllTestCounter == 0, message = "beforeAllTests block should run only once")
UltronLog.info("UltronTest simpleTest")
}
}
52 changes: 52 additions & 0 deletions composeApp/src/commonTest/kotlin/UltronTestFlowTest2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import com.atiurin.ultron.annotations.ExperimentalUltronApi
import com.atiurin.ultron.core.test.UltronTest
import com.atiurin.ultron.log.UltronLog
import kotlin.test.Test
import kotlin.test.assertTrue

class UltronTestFlowTest2 : UltronTest() {
var order = 0
var beforeAllTestCounter = 0

@OptIn(ExperimentalUltronApi::class)
override val beforeFirstTests = {
beforeAllTestCounter = order
order++
UltronLog.info("Before Class")
}

@Test
fun someTest1() = test {
var beforeOrder = -1
var afterOrder = -1
var goOrder = -1
order++
before {
beforeOrder = order
order++
UltronLog.info("Before TestMethod 1")
}.go {
goOrder = order
order++
UltronLog.info("Run TestMethod 1")
}.after {
afterOrder = order
assertTrue(beforeAllTestCounter == 0, message = "beforeAllTests block should run before all test")
assertTrue(beforeOrder > beforeAllTestCounter, message = "Before block should run after 'Before All'")
assertTrue(beforeOrder < goOrder, message = "Before block should run before 'go'")
assertTrue(goOrder < afterOrder, message = "After block should run after 'go'")
}
}

@Test
fun someTest2() = test(suppressCommonBefore = true) {
before {
UltronLog.info("Before TestMethod 2")
}.after {
UltronLog.info("After TestMethod 2")
}.go {
assertTrue(beforeAllTestCounter == 0, message = "beforeAllTests block should run only once")
UltronLog.info("Run TestMethod 2")
}
}
}
2 changes: 1 addition & 1 deletion docs/docs/common/boolean.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 5
---

# Boolean result
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/common/extension.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 1
sidebar_position: 3
---

# Ultron Extension
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/common/listeners.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 3
sidebar_position: 4
---

# Listeners
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/common/resulthandler.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 5
sidebar_position: 7
---

# Result handler
Expand Down
141 changes: 141 additions & 0 deletions docs/docs/common/ultrontest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
sidebar_position: 2
---

# UltronTest

Using `UltronTest` as a Base Class for Tests

`UltronTest` is a powerful base class provided by the Ultron framework that enables the definition of common preconditions and postconditions for tests. By extending this class, you can streamline test setup and teardown, ensuring consistent execution across your test suite.

## Features of `UltronTest`

- **Pre-Test Actions:** Define actions to be executed before each test.
- **Post-Test Actions:** Define actions to be executed after each test.
- **Lifecycle Management:** Execute code once before all tests in a class using `beforeFirstTests`.
- **Customizable Test Execution:** Suppress pre-test or post-test actions when needed.

### Example

Here is an example of using `UltronTest`:

```kotlin
class SampleUltronFlowTest : UltronTest() {

@OptIn(ExperimentalUltronApi::class)
override val beforeFirstTests = {
UltronLog.info("Before Class")
}

override val beforeTest = {
UltronLog.info("Before test common")
}

override val afterTest = {
UltronLog.info("After test common")
}

/**
* An order of methods execution is follow:
* beforeFirstTests, beforeTest, before, go, after, afterTest
*/
@Test
fun someTest1() = test {
before {
UltronLog.info("Before TestMethod 1")
}.go {
UltronLog.info("Run TestMethod 1")
}.after {
UltronLog.info("After TestMethod 1")
}
}

/**
* An order of methods execution is follow: before, go, after
* `beforeFirstTests` - not executed, since it was executed before `someTest1`
* `beforeTest` - not executed, as it was suppressed
* `afterTest` - not executed, as it was suppressed
*/
@Test
fun someTest2() = test(
suppressCommonBefore = true,
suppressCommonAfter = true
) {
before {
UltronLog.info("Before TestMethod 2")
}.go {
UltronLog.info("Run TestMethod 2")
}.after {
UltronLog.info("After TestMethod 2")
}
}

/**
* An order of methods execution is follow: beforeTest, test, afterTest
* `beforeFirstTests` - not executed, since it was executed before `someTest1`
*/
@Test
fun someTest3() = test {
UltronLog.info("UltronTest simpleTest")
}
}
```

### Key Methods

- **`beforeFirstTests`**: Code executed once before all tests in a class.
- **`beforeTest`**: Code executed before each test.
- **`afterTest`**: Code executed after each test.
- **`test`**: Executes a test with options to suppress pre-test or post-test actions.

---

## Using `softAssertion` for Flexible Error Handling

The `softAssertion` mechanism in Ultron allows tests to catch and verify multiple exceptions during their execution without failing immediately. This feature is particularly useful for validating multiple conditions within a single test.
### Example of `softAssertion`

```kotlin
class SampleTest : UltronTest() {
@Test
fun softAssertionTest() {
softAssertion(failOnException = false) {
hasText("NotExistText").withTimeout(100).assertIsDisplayed()
hasTestTag("NotExistTestTag").withTimeout(100).assertHasClickAction()
}
verifySoftAssertions()
}
}
```

The `softAssertion` is not generally depends on `UltronTest`.
You can use it outside `UltronTest` base class. But you have to clear exceptions between tests
```kotlin
class SampleTest {
@Test
fun softAssertionTest() {
UltronCommonConfig.testContext.softAnalyzer.clear()
softAssertion() {
//assert smth
}
}
}
```

### Explanation

- **Fail on Exception:** By default (`failOnException = true`), `softAssertion` will throw an exception after completing all operations within its block if any failures occur.
- **Manual Verification:** If `failOnException` is set to `false`, you can explicitly verify all caught exceptions at the end of the test using `verifySoftAssertions()`.

This approach ensures granular control over how exceptions are handled and reported, making it easier to analyze and debug test failures.

---

## Benefits

- Simplifies test setup and teardown with consistent preconditions and postconditions.
- Enhances error handling by allowing multiple assertions within a single test.
- Improves test readability and maintainability.

By leveraging `UltronTest` and `softAssertion`, you can build robust and flexible UI tests for your applications.

10 changes: 0 additions & 10 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 782bc81

Please sign in to comment.