Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wiki #2

Merged
merged 2 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Kaspresso

[![CircleCI](https://circleci.com/gh/matzuk/Kaspresso.svg?style=svg&circle-token=705dd95e0d0b528b0b59e1b638cfa7c9e7659500)](https://circleci.com/gh/matzuk/Kaspresso)

Kaspresso is a UiTest framework based on [Espresso](https://developer.android.com/training/testing/espresso),
[UIAutomator](https://developer.android.com/training/testing/ui-automator) and
[Kakao](https://github.com/agoda-com/Kakao) and assisting to write right and no-pain ui tests.
Expand Down Expand Up @@ -105,7 +103,7 @@ Part of interceptors was introduced in Kakao version 2.1, another part of interc
#### Ability to call Adb commands

Espresso or UiAutomator doesn't allow to call adb commands inside a test.
That's why we have written special [AdbServer repository](https://github.com/matzuk/AdbServer) fixing mentioned problem.
That's why we have written special [AdbServer repository](https://github.com/KasperskyLab/AdbServer) fixing mentioned problem.

In Kaspresso, the developer can call adb and cmd commands by ```AdbServer``` class.
#### Ability to work with Android System
Expand All @@ -131,17 +129,17 @@ The developer can tune any part of Kaspresso thanks to ```Kaspresso.Builder```.
Kaspresso proposes such very important things for ui-tests as the set of rules on how to write ui-tests.

## Wiki
For all information check [Kaspresso wiki](https://github.com/matzuk/Kaspresso/wiki)
For all information check [Kaspresso wiki](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/00.%20Home.md)

## Integration
// todo

## Links
// todo
## Support
Russian support in telegram - t.me/kaspresso

## Contribution Policy
Kaspresso is an open source project, and depends on its users to improve it. We are more than happy to find you interested in taking the project forward. <br>
Kindly refer to the [Contribution Guidelines](https://github.com/matzuk/Kaspresso/blob/master/CONTRIBUTING.md) for detailed information. <br>
Kindly refer to the [Contribution Guidelines](https://github.com/KasperskyLab/Kaspresso/blob/master/CONTRIBUTING.md) for detailed information. <br>

## License
Kaspresso is open source and available under the [Apache License, Version 2.0](https://github.com/matzuk/Kaspresso/blob/external_master/LICENSE).
Kaspresso is open source and available under the [Apache License, Version 2.0](https://github.com/KasperskyLab/Kaspresso/blob/master/LICENSE).
15 changes: 15 additions & 0 deletions wiki/00. Home.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Home

Kaspresso is a UiTest framework based on Espresso, UIAutomator and Kakao and assisting to write right and no-pain ui tests.

## Content
[01. Kaspresso configurator](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/01.%20Kaspresso%20configurator.md) <br>
[02. How to write autotests and appropriate test structure](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/02.%20How%20to%20write%20autotests%20and%20appropriate%20test%20structure.md) <br>
[03. Device](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/03.%20Device.md) <br>
[04. AdbServer](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/04.%20AdbServer.md) <br>
[05. DocLoc](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/05.%20DocLoc.md) <br>

## References

[RU] [Дмитрий Мовчан, Евгений Мацюк — Как начать писать автотесты и не сойти с ума](https://www.youtube.com/watch?v=q_8UUhVDV7c&list=PLb1A91j1236qyWB8mBbWF_FN6fC4ztPXG&index=20&t=0s) <br>
[RU] [Александр Блинов — Kotlin DSL, Fixtures и элегантные UI тесты в Android](https://habr.com/ru/company/hh/blog/455042/)
157 changes: 157 additions & 0 deletions wiki/01. Kaspresso configurator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Kaspresso configurator

**Kaspresso** class - is a single point to set Kaspresso parameters. <br>
A developer can customize **Kaspresso** by setting ```Kaspresso.Builder``` at constructors of ```TestCase```, ```BaseTestCase```, ```TestCaseRule```, ```BaseTestCaseRule```.

### Structure

All settings in **Kaspresso** class may be divided into four groups: <br>

#### Loggers
```libLogger``` - inner Kaspresso logger <br>
```testLogger``` - logger available for developers in tests. <br>
It's available by ```testLogger``` property in test sections (```before, after, init, transform, run```) in test dsl (by ```TestContext``` class). <br>
Also it is availaible while setting ```Kaspresso.Builder``` if you want to add it to your custom interceptors, for example.<br>

#### Kaspresso interceptors based on Kakao Interceptors.
These interceptors were introduced to simplify and uniform using of [Kakao interceptors](https://github.com/agoda-com/Kakao#intercepting).<br> <br>
_**Important moment**_ about a mixing of Kaspresso interceptors and Kakao interceptors. <br>
Kaspresso interceptors will not work if You set your custom Kakao interceptors by calling of ```Kakao.intercept``` method in the test. <br>
If you set your custom Kakao interceptors for concrete ```Screen``` or ```KView``` and set argument ```isOverride``` in true then Kaspresso interceptors will not work for concrete ```Screen``` or ```KView``` fully.
<br> <br>
Kaspresso interceptors can be divided into two types: <br>
1. ```Behavior Interceptors``` - are intercepting calls to ViewInteraction, DataInteraction, WebInteraction and do some stuff. **Attention**, we will consider some important notes about ```Behavior Interceptors``` at the end of this document. <br>
2. ```Watcher Interceptors``` - are intercepting calls to ViewAction, ViewAssertion, Atom, WebAssertion and do some stuff. <br>

Let's expand mentioned Kaspresso interceptors types: <br>
1. ```Behavior Interceptors```
1. ```viewBehaviorInterceptor``` - intercept calls to ```ViewInteraction#perform``` and ```ViewInteraction#check``` <br>
2. ```dataBehaviorInterceptor``` - intercept calls to ```DataInteraction#check``` <br>
3. ```webBehaviorInterceptor``` - intercept calls to ```Web.WebInteraction<R>#perform``` and ```Web.WebInteraction<R>#check``` <br>
2. ```Watcher Interceptors```
1. ```viewActionWatcherInterceptors``` - do some stuff before [android.support.test.espresso.ViewAction.perform] is actually called <br>
2. ```viewAssertionWatcherInterceptors``` - do some stuff before [android.support.test.espresso.ViewAssertion.check] is actually called <br>
3. ```atomWatcherInterceptors``` - do some stuff before [android.support.test.espresso.web.model.Atom.transform] is actually called <br>
4. ```webAssertionWatcherInterceptors``` - do some stuff before [android.support.test.espresso.web.assertion.WebAssertion.checkResult] is actually called <br>

#### Special Kaspresso interceptors
These interceptors are not based on some lib. Short description:
1. ```stepWatcherInterceptors``` - an interceptor of **Step** lifecycle actions
2. ```testRunWatcherInterceptors``` - an interceptor of entire **Test** lifecycle actions

As you noticed it's also a part of ```Watcher Interceptors```.

#### Device
```Device``` instance. Detailed info is at [Device wiki](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/03.%20Device.md)

#### AdbServer
```AdbServer``` instance. Detailed info is at [AdbServer wiki](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/04.%20AdbServer.md)

### Using

All actions to add Kaspresso in the test where Espresso and Kakao are using is one of:
- extend ```BaseTestCase``` or ```TestCase```
- add ```BaseTestCaseRule``` or ```TestCaseRule``` rule field in your test

### Kaspresso configuring and Kaspresso interceptors example

The example of how to configure Kaspresso and how to use Kaspresso interceptors are in [configurator](https://github.com/KasperskyLab/Kaspresso/tree/master/sample/src/androidTest/java/com/kaspersky/kaspressample/configurator_tests).

### Default Kaspresso settings
```BaseTestCase```, ```TestCase```, ```BaseTestCaseRule```, ```TestCaseRule``` are using default customized **Kaspresso**. <br>
Most valuable features of default customized **Kaspresso** are below.

#### Logging
Just start [SimpleTest](https://github.com/KasperskyLab/Kaspresso/blob/master/sample/src/androidTest/java/com/kaspersky/kaspressample/simple_tests/SimpleTest.kt). Next, you will see those logs:
```
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: BEFORE TEST SECTION
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: TEST SECTION
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "1. Open Simple Screen" in SimpleTest
I/KASPRESSO_SPECIAL: I am kLogger
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@95afab5' assertion on view (with id: com.kaspersky.kaspressample:id/activity_main_button_next)
I/KASPRESSO: Check view has effective visibility=VISIBLE on AppCompatButton(id=activity_main_button_next;text=Next;)
I/KASPRESSO: single click on AppCompatButton(id=activity_main_button_next;text=Next;)
I/KASPRESSO: TEST STEP: "1. Open Simple Screen" in SimpleTest SUCCEED. It took 0 minutes, 0 seconds and 618 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "2. Click button_1 and check button_2" in SimpleTest
I/KASPRESSO: single click on AppCompatButton(id=button_1;text=Button 1;)
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@9f38781' assertion on view (with id: com.kaspersky.kaspressample:id/button_2)
I/KASPRESSO: Check view has effective visibility=VISIBLE on AppCompatButton(id=button_2;text=Button 2;)
I/KASPRESSO: TEST STEP: "2. Click button_1 and check button_2" in SimpleTest SUCCEED. It took 0 minutes, 0 seconds and 301 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "3. Click button_2 and check edit" in SimpleTest
I/KASPRESSO: single click on AppCompatButton(id=button_2;text=Button 2;)
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@ad01abd' assertion on view (with id: com.kaspersky.kaspressample:id/edit)
I/KASPRESSO: Check view has effective visibility=VISIBLE on AppCompatEditText(id=edit;text=Some text;)
E/KASPRESSO: Failed to interact with view matching: (with id: com.kaspersky.kaspressample:id/edit) because of AssertionFailedError
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@d0f1c0a' assertion on view (with id: com.kaspersky.kaspressample:id/edit)
I/KASPRESSO: Check view has effective visibility=VISIBLE on AppCompatEditText(id=edit;text=Some text;)
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@3b62c7b' assertion on view (with id: com.kaspersky.kaspressample:id/edit)
I/KASPRESSO: Check with string from resource id: <2131558461> on AppCompatEditText(id=edit;text=Some text;)
I/KASPRESSO: TEST STEP: "3. Click button_2 and check edit" in SimpleTest SUCCEED. It took 0 minutes, 2 seconds and 138 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "4. Check all possibilities of edit" in SimpleTest
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "4.1. Change the text in edit and check it" in SimpleTest
I/KASPRESSO: replace text on AppCompatEditText(id=edit;text=Some text;)
I/KASPRESSO: type text(111) on AppCompatEditText(id=edit;)
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@dbd9c8' assertion on view (with id: com.kaspersky.kaspressample:id/edit)
I/KASPRESSO: Check with text: is "111" on AppCompatEditText(id=edit;text=111;)
I/KASPRESSO: TEST STEP: "4.1. Change the text in edit and check it" in SimpleTest SUCCEED. It took 0 minutes, 0 seconds and 621 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "4.2. Change the text in edit and check it. Second check" in SimpleTest
I/KASPRESSO: replace text on AppCompatEditText(id=edit;text=111;)
I/KASPRESSO: type text(222) on AppCompatEditText(id=edit;)
I/ViewInteraction: Checking 'com.kaspersky.kaspresso.proxy.ViewAssertionProxy@b8ca74' assertion on view (with id: com.kaspersky.kaspressample:id/edit)
I/KASPRESSO: Check with text: is "222" on AppCompatEditText(id=edit;text=222;)
I/KASPRESSO: TEST STEP: "4.2. Change the text in edit and check it. Second check" in SimpleTest SUCCEED. It took 0 minutes, 0 seconds and 403 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: TEST STEP: "4. Check all possibilities of edit" in SimpleTest SUCCEED. It took 0 minutes, 1 seconds and 488 millis.
I/KASPRESSO: ___________________________________________________________________________
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: AFTER TEST SECTION
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: TEST PASSED
I/KASPRESSO: ---------------------------------------------------------------------------
I/KASPRESSO: ---------------------------------------------------------------------------
```
Pretty good.

#### Screenshots
A developer receives a screenshot after each Step and after any error. Screenshots are saving at Device in "sdcard/screenshots/".

### Some words about Behavior Interceptors
Any lib for ui-tests is flaky. It's a hard truth of life. Any action/assert in your test may fail for some undefined reason. <br>
What kinds of flaky errors are exist:
1. Common flaky errors that happened because Espresso was in a bad mood =) <br>
That's why Kaspresso wraps **all** actions/assertions of Kakao and handles set of potential flaky exceptions.
If an exception happened then Kaspresso attempts to repeat failed actions/assert for 2 seconds. Such handling rescues developers of any flaky action/assert.<br>
The details are at [flakysafety](https://github.com/KasperskyLab/Kaspresso/tree/master/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/flakysafety). <br>
2. If the fault is due to an interaction with an element which is not visible and to which you need to scroll, Kaspresso will try to fix it by performing an autoscroll action by itself. <br>
The details are at [autoscroll](https://github.com/KasperskyLab/Kaspresso/tree/master/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/autoscroll). <br>
3. Also, Kaspresso attempts to remove all system dialogs if it prevents the test executes. <br>
The details are at [systemsafety](https://github.com/KasperskyLab/Kaspresso/tree/master/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/systemsafety). <br>

These handlings are possible thanks to ```BehaviorInterceptors```. Also, you can set your custom handlings by ```Kaspresso.Builder```. But remember the order of ```BehaviorInterceptors``` is significant: the first item will be at the lowest level of intercepting chain, and the last item will be at the highest level. For example, the first item actually wraps the ```androidx.test.espresso.ViewInteraction.perform``` call, the second item wraps the first item, and so on. <br>
Let's consider the order of ```BehaviorInterceptors``` enabled by default in Kaspresso. It's: <br>
1. ```AutoScrollViewBehaviorInterceptor```
2. ```SystemDialogSafetyViewBehaviorInterceptor```
3. ```FlakySafeViewBehaviorInterceptor```
4. ```FailureLoggingViewBehaviorInterceptor```

When Kakao intercepting is than the chain is <br>
```FailureLoggingViewBehaviorInterceptor``` calls ```FlakySafeViewBehaviorInterceptor``` that calls ```SystemDialogSafetyViewBehaviorInterceptor``` and that calls ```AutoScrollViewBehaviorInterceptor```. <br>
If a result of ```AutoScrollViewBehaviorInterceptor``` handling is an error then ```SystemDialogSafetyViewBehaviorInterceptor``` attempts to handle received error. If a result of ```SystemDialogSafetyViewBehaviorInterceptor``` handling is an error also then ```FlakySafeViewBehaviorInterceptor``` attempts to handle received the error. And so on. <br>
To simplify all described above we have drawn a picture:

![](https://habrastorage.org/webt/vd/0l/yi/vd0lyifmooskcw3asm_19qqycke.png)
Loading