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

Add Best Practices to Kaspresso Wiki #162

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ele638
Copy link
Contributor

@ele638 ele638 commented Jun 7, 2020

close #131

@matzuk matzuk self-requested a review June 8, 2020 04:14
└── java
└── com
├── actions
├── app_providers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование нижних подчеркиваний в названиях пакетов противоречит
https://developer.android.com/kotlin/style-guide#package_names

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, соглашусь

```

1. **App_providers**
Put here all helper classes wich contains some business logic of main application. For example, if you need to use some Dagger component and check state of your interactor. **Don't use this interactors directly,** put accessing to interactors into method-wrappers witch returns some primitive or void for some simple actions and then call this methods in your test cases.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state of your interactor

О каком состоянии интерактора речь? Интерактор - это функция, состояние хранится в репозитории.

**Don't use this interactors directly

Не понял, что подразумевается по "прямым" и не "прямым" использованием. Давай добавим примеры.

**Don't use this interactors directly

Почему? К каким последствиям это может привести?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, стоит чуть подраскрыть. Человеку, который не в контексте, будет тяжело понять, что к чему.

├── screens
├── screenshot_tests
├── tests
└── views
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нет описания, что это за пакет и какие там views хранятся

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, как-то упустили

```

3. **Functional**
This package needed for converting end-to-end tests into functional, for example it's may be working with DI, stub's and Advice. (Here is more about [Advice](#Advices))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Такие тесты обычно называют интеграционными. Почему functional?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я согласен, что нужно переименовать, ибо функциональные тесты сами по себе немного про другое
@RuslanMingaliev как назовем?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Надо пообщаться с нашим QA, чтобы не было недопониманий

3. **Functional**
This package needed for converting end-to-end tests into functional, for example it's may be working with DI, stub's and Advice. (Here is more about [Advice](#Advices))
4. **Scenarios**
There you can hold your mostly repeated steps wrapped into scenarios. In common it created with kotlin stateless objects. But you can hold some parameters for some logic and in this case create classic class with constructor parameters. We highly recommend to separate scenarios if it contains so many steps and logic. (Here is some more about [`scenario`](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/04_How_to_write_autotests.md#test-structure-1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it contains so many steps and logic

лучше давать количественную характеристику, а не качественную. Не понятно, 100 шагов норм или уже нет


1. First rule of writing best test cases: inheritors of `TestCase` class must be exactly test cases or class wich overrides **must be applied to all test cases**. If you create multiple parent classes you may get pain with modifying and ordering classes or your new cases may do some work wich them must not to do.

But if you still needed to add some actions to group of cases you can create lamda-function with `Kaspresso.Builder` (here is more about [`Kaspresso.Bulder`](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/03_Kaspresso_configurator.md)) receiver and pass it as class parameter. You still can use `before` and `after` sections in test case but also you will have `beforeEachTest` and `afterEachTest`. Example:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add some actions to group of cases

Если речь только про beforeEachTest и afterEachTest, то это не some actions, а конкретные actions. Нельзя добавить шаги куда-то в середину. Кажется, мы тут вводим в заблуждение.

## Other advices

1. Don't be afraid to read source code of called methods. For example you can discover that method `androidx.test.uiautomator.UiDevice.pressBack()` calling `waitForIdle()` before perfoming click. This waiting by default keep 10 seconds timeout and may not execute if screen still drawing some changes.
And if you go deeper in code researching you can find configurator of uiAutomator and change default timeout of `waitForIdle()`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Технология называется UI Automator


```kotlin
/**
* More efficient simple waiting then Thread.sleep
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More efficient

Стоит указать, чем эффективнее

}
```

3. There is difference of `device.targetContext` and `device.context`. First one used if you need context of **application witch will be tested** (host application) and second one if you need context of **application wich testing your main application** (slave application).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Откуда терминология host application и slave application?

}
```

5. Use `assertSafely` constructions. From naming you can realise that it's [`flakySafely`](https://github.com/KasperskyLab/Kaspresso/blob/master/wiki/04_How_to_write_autotests.md#flakysafely), for assertions and used when your assert may be appear with some delay. Also you can set custom message of error.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что за конструкция assertSafely? Неплохо было бы увидеть пример. Из описания не понятно, что это и чем отличается от flakySafely

@RuslanMingaliev
Copy link
Collaborator

Английский нужно вычитывать. Нашел много грамматических, пунктуационных и синтаксических ошибок.

...
step("some step") {
MainScreen {
Accessibility.run { enable() } // without invoke override
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tab vs space

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, поехало шо то


## File structure

Here is shown an example structure of packages. It's not strong rule but we higly recommend to organize your files.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example of the package structure is shown here. It's not a very strict rule but we strongly recommend organizing your files in such an order.

└── java
└── com
├── actions
├── app_providers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, соглашусь

├── screens
├── screenshot_tests
├── tests
└── views
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, как-то упустили

```

1. **App_providers**
Put here all helper classes wich contains some business logic of main application. For example, if you need to use some Dagger component and check state of your interactor. **Don't use this interactors directly,** put accessing to interactors into method-wrappers witch returns some primitive or void for some simple actions and then call this methods in your test cases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wich

that

```

1. **App_providers**
Put here all helper classes wich contains some business logic of main application. For example, if you need to use some Dagger component and check state of your interactor. **Don't use this interactors directly,** put accessing to interactors into method-wrappers witch returns some primitive or void for some simple actions and then call this methods in your test cases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains

contain


For describing views use childs of KView (kakao views).

### KExternalScreen
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну мы же специально разделяли UiScreen и немного проапгреденный KExternalScreen


### KExternalScreen

If you want write autotests with external screens (when your app use another app, like Chrome or Gmail) you can create class for external screens, for example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want write autotests with external screens (when your app use another app, like Chrome or Gmail) you can create class for external screens, for example

Нужно написать, что бывают случаи, когда из тестов мы юзаем другие приложения, но и в этих случаях лучше придерживать паттерна PO и описывать каждый экран. Для описания экранов внешних приложений можно использовать KExternalScreen, который по своей сути очень походит на KScreen.
И вот в таком духе описывай.

}
```

Or if you don't want to override `invoke` you may not use generics.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

какие дженерики??


## Advices

If you want to separate end-to-end and functional test cases in single code of test we recommend to use interfaces and we named it `Advice` (but you can name it as you want). For example we want to pass registration on web-portal in our application. In e2e we must perform real registration but on functional we can stub it. So let's write some code:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно вообще начинать с проблемы.
Прям бери с нашего с Мовчаном выступления.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему "advice"?)))

## Advices

If you want to separate end-to-end and functional test cases in single code of test we recommend to use interfaces and we named it `Advice` (but you can name it as you want). For example we want to pass registration on web-portal in our application. In e2e we must perform real registration but on functional we can stub it. So let's write some code:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ниже не стал проходиться сильно, так как основные моменты описаны уже выше.
Каждый пункт нужно начинать с истории, проблемы, продолжать примерами и четким разъяснением.
PR нужно еще серьезно дорабатывать, но начало положено.

@AzamatCherchesov AzamatCherchesov marked this pull request as draft November 30, 2022 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Описать Лучшие практики в Wiki
4 participants