ืืืืืื ืฉืื ื ืืืฆืจืช ืฆืื ืืจืืช ืืืืืืืืื ืืืืืืื ืืืฉืงืช ืืจืกืืืช ืืืฉืืช ืฉื ืืืฉืืืื ืืชืื ืกืืืืช ืืืืฆืืจ. ืืืืื, ืื ืืืจืฉ ืืืืงืืช ืคืื ืงืฆืืื ืืืืช ืืืืืืืืืช. ืืชืืช ืืืืชืื ืืฉ ืกืืคืืจ ืขื ืืื, ืืื ืืืืืงืช ืืื ืืืื ืืืืื ื ืืงืืืืช, ืืืขื ื ืื ืงืืื ืฉื ืืืืงื ืืืืืืืืช ืืจืืื ืืืืื ืืคืืขืืช ืขื Selenoid ืืฆื ืจืช ืืื ืืื ืขื ืืื Allure ืืืคื GitLab ืืืกืืคื ืฉื ืืืจ ืงืืืื ื ืืื ืืืืืืฆืื ืืื ืื ืฉืื ืฉืื ืขืชืืืืื ืืืืื ืืืฉืชืืฉ ืืฆืืืชืื.
ืืืืคื ืืชืืื ื?
ืืื ืืืืฉื ืืืืงืืช ืืืืืืืืืช ืืืฉืื ืืืชื ืืฆื ืจืช, ืืืื ื ืฆืจืืืื ืืกืืจืช ืืืืืืฆืื ืฉื ืืชื ืืฉื ืืช ืืืืืฉืืช ืืื ืืืชืืื ืืฆืจืืื ืฉืื ื. ืืืืคื ืืืืืืื, ืจืฆืืชื ืืงืื ืชืงื ืืืื ืขืืืจ ืื ืืข ืืืืืงื ืืืืืืืืืช, ืืืืชืื ืืืืืขืช ืืืืงืืช ืืืืืืืืืช ืืฆืื ืืจ. ืืืืฉืื ืืืจื ื ืืืื ืืืืืืืช ืืืืืช:
- ื'ืืืื,
- ืืืืื,
- ืกึตืึถื ึดืืึผื,
- ืืืคืคืื+ื'ืื ืื 4,
- ืงึถืกึถื,
- GitLab.
ืืื ืืืืงื ืืกื ืืื? Java ืืื ืืืช ืืฉืคืืช ืืคืืคืืืจืืืช ืืืืชืจ ืืืืืงืืช ืืืืืืืืืช, ืืื ืืืจื ืืฆืืืช ืืืืจืื ืืืชื. ืกืื ืืื ืืื ืืคืชืจืื ืืืจืืจ. ืืืคืคืื, ืืื ืืืชืจ, ืืื ืืืืจ ืืืืืืจ ืืช ืืืืื ืืชืืฆืืืช ืฉื ืืืืงืืช ืืืืืืืืืช ืืฆื ืืืืงืืช ืืขืืกืงืืช ืืืืืงืืช ืืื ืืืช.
ืืืืงืืช ืขื ืืืจืื ืืืืืช
ืืื ืื ืืืืฆืื ืืช ืืืืื ืืืืฉ ืืงืื ื ืคืืชืืืื ืืืืืจืื ืฉืื ืื ื-GitHub ืืืกืืก ืืืกืืจืช ืืืชืืื ื ืืืชื ืืขืฆืื ื. ืืฆืจื ื ืืืืจ ืขืืืจ ืืกืคืจืืื ืืจืืฉืืช ืขื ืืืืื ืฉื ืืกืืจืช ืืืืืงื ืืืืืืืืืช ืืืืืจ ืขื ืืืืื ืฉื ืืื ืฉื ืืืืขืช ืืืืงืืช ืืืืืืืืืช ืืืืื ืฉืื ื. ืื ืฆืืืช ืืื ืฆืจืื ืืงืืช ืืช ืชืืื ืช ืืืื ืืืคืชื ืื ืืืื ืื, ืืืชืืื ืืืชื ืืคืจืืืงื ืฉืื. ืคืจืกื ื ืืช ืื ืืื ืง GitLab-CI, ืฉืื ืืืืจื ื:
- ืจืืฆืืช ืืืืืืช ืฉื ืื ืืืืืงืืช ืืืืืืืืืืช ืืืชืืืืช ืขืืืจ ืื ืคืจืืืงื;
- ืืฉืงืืช ืืฆื ืจืช ืืื ืืื.
ืืืชืืื ืืื ืืขื ืืืืงืืช, ืืื ืืืฆืขื ืืืจื ืืื. ืจืืฆื ืขื ืคืชืื ืืืื ืขื ืจืฅ Windows GitLab ืืชืืืื ืื ื ืืืื: ืืืืืงืืช ืืขืืืกื ืืช ืกืคืกื ืืืืืงื ืืงืืืืืช ืจืื ืืื ืืฉืชืืฉื ืืืขื ืืืฉืืืื.
ืขื ืืืื, ืืกืคืจ ืืืืืงืืช ืืืืืืืืืืช ืืื ืืืชืจ ืืืืชืจ, ืืืฉืื ื ืืืคืขืื ืืืชื ืืืงืืื, ืืืฉืจ ืจืืฆื ืืืื ืืืื ืืืจืื ืืฉืืืฉ ืฉืขืืช. ืืขืืืช ื ืืกืคืืช ืืืคืืขื ืื:
- ืื ืืืืื ื ืืืืื ืฉืืืืืงืืช ืืื ืืฆืืืืช;
- ืืืืงืืช ืฉืืืคืขืื ืืกืคืจ ืคืขืืื ืืจืฆืืคืืช ืืืืื ื ืืืงืืืืช ืงืจืกื ืืคืขืืื ื-CI.
ืืืืื ืืืืืจืช ืืืืงืืช ืืืืืืืืืช:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skipTests>${skipTests}</skipTests>
<testFailureIgnore>false</testFailureIgnore>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.9</version>
</plugin>
</plugins>
ืืืืื ืืืื ืคืืชืื
ืขืืืก ืจืฅ ืืืืื ืืืืงืืช (8 ืืืืืช, 8 GB RAM, ืืื ืืื)
ืืืชืจืื ืืช ืฉื ืืืื ืื ืขื ืืื ืืืื:
- ืงื ืืืืืืจ ืืืืคืขืื;
- ืืืฉืงืืช ื-CI ืืืขื ืืืื ื ืฉืื ืืช ืืืฉืงืืช ืืงืืืืืช;
- ืืืืงืืช ืืื ื ืืฉืคืืขืืช ืืืช ืขื ืืฉื ืืื;
- ืืจืืฉืืช ืืื ืืืื ืืืฉืืื ืจืฆืื.
ืืกืจืื ืืช ืฉื ืืืืงืืช ืืื ืืืื:
- ืืืงื ืืจืื ืืืื ืืื ืืืฉืืื;
- ืืืฆืื ืืจืื ืฉื ืืืืงืืช;
- ืฉืืืืฉ ืื ืืขืื ืืืฉืืื ืืจืฆืื, ื ืืฆืื ื ืืื ืืืืืื.
ืืืืงืืช ืขื ืืืืืืช JVM
ืืืืืื ืฉืื ืืงืคืื ื ืขื ืงืื ืืืื ืืฉืจืฉืืจ ืืขืช ืืืืขืช ืืกืืจืช ืืืกืืก, ืืืจื ืืืจืืจื ืืืืชืจ ืืจืืฅ ืืืงืืื ืืืืชื
ืฉืจืช ืืกืื ืืืื ืืืฉืง ืืืืื ื ืืขืืช 32 ืืืืืช ื-24 ื'ืืื-ืืืื ืฉื ืืืืจืื RAM. ืืืืืื ื ืงืืขื ื-48 ืืคืืคื ืื - 1,5 ืฉืจืฉืืจืื ืืื ืืืื ืื-400 ืืื-ืืืื ืฉื ืืืืจืื RAM. ืืชืืฆืื ืืื, ืืื ืืืืืงื ืฆืืืฆื ืืฉืืืฉ ืฉืขืืช ื-40 ืืงืืช. ืืืฆืช ืืจืืฆืืช ืขืืจื ืืคืชืืจ ืืช ืืขืืืช ืืืืฆืื: ืืขืช ื ืืื ืืืจืืฅ ืืืืืจืืช ืืืืงืืช ืืืืืืืืืช ืืืฉืืช 20-30 ืคืขืืื ืขื ืฉืืืื ื ืืืืืื ืฉืื ืคืืขืืืช ืืฆืืจื ืืืืื ื.
ืืืืกืจืื ืืจืืฉืื ืฉื ืืคืชืจืื ืืื ื ืืฆืื ืืืื ืฉื ืืฉืืื ืจืื ืจ ืขื ืืกืคืจ ืงืื ืฉื ืคืชืืืื ืืงืืืืื: ืขื 4 ืืืืืช ื-8 GB ืฉื ืืืืจืื RAM, ืืืืืงืืช ืจืฆื ืืืฆืืืืช ืืื ืืืชืจ ื-6 ืคืชืืืื. ืืืืกืจืื ืืฉื ื: ืืชืืกืฃ ืืืืฆืจ ืืืชืืช ืจืฆืื ืืื ืชืจืืืฉ, ืื ืืฉื ื ืืื ืืื ืืืคืขืื.
ืืฉืื! ืื ืชืขืืืจ ืืฉืชื ื ืขื ืชืืื ื argLine, ืืืฉื, ืื:
<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine>
โฆ
Mvn โDTAGS="@smoke"
ืื ืชืขืืืจื ืืช ืืชื ืืฆืืจื ืื, ืืชืืกืฃ ืืคืืง ืจืฆืื ืืื ืืืืืงืืช, ืืืืืจ ืื ืกื ืืืจืืฅ ืืช ืื ืืืืืงืืช, ืืืื ืขืืืื ืืื ืืืืจ ืืืฉืงื ืืืืฆืืจ ืืืืืืช ืจืืื ืฉื JVM.
ื ืืื ืืืจืืง ืืชืืื ืืฉืชื ื ืขื ืชื ืชืืืืื ืืืืืจืืช ืืคืืืืื, ืจืื ืืืืื ืืืื. ืืฉืืืืช ืืืจืืช ืฉืืืงื ื ืืฉ ืืขืืืช ืืืืืืจ ืืชืืกืฃ Allure.
ืืืืื ืืืื ืจืืฆื ืขืืืจ 6 ืืืืงืืช ืงืฆืจืืช ืขื ืืืืจืืช ืฉืืืืืช:
[INFO] Total time: 03:17 min
ืืืืื ืืืื ืจืืฆืช ืืืืงื ืื ืืชื ืืขืืืจ ืืฉืืจืืช ืืช ืืชื ืื mvn... โDcucumber.options:
[INFO] Total time: 44.467 s
ืืืืื ืืืืืจืช ืืืืงืืช ืืืืืืืืืช:
<profiles>
<profile>
<id>parallel</id>
<build>
<plugins>
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<tags>
<tag>${TAGS}</tag>
</tags>
<glue>
<package>stepdefs</package>
</glue>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<forkCount>12</forkCount>
<reuseForks>false</reuseForks>
<includes>**/*IT.class</includes>
<testFailureIgnore>false</testFailureIgnore>
<!--suppress UnresolvedMavenProperty -->
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" -Dcucumber.options="--plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm TagPFAllureReporter --plugin pretty"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
ืืืืื ืืืื Allure (ืืืืืงื ืืื ืื ืืฆืืื, 4 ืฉืืืืจืื ืืืืจืื)
ืขืืืก ืจืฅ ืืืืื ืืืืงืืช (8 ืืืืืช, 8 GB RAM, 12 ืคืชืืืื)
ืืชืจืื ืืช:
- ืืืืจื ืงืื - ืืชื ืจืง ืฆืจืื ืืืืกืืฃ ืชืืกืฃ;
- ืืืืืืช ืืืฆืข ืื ืืื ืืช ืืกืคืจ ืจื ืฉื ืืืืงืืช;
- ืืืฆืช ืืืฆืื ืืืืืงื ืืืืืช ืืฉืื 1.
ืืกืจืื ืืช:
- ื ืืจืฉืืช ืืกืคืจ ืืขืจืืืช ืืคืขืื/ืืืืืืช;
- ืฆืจืืืช ืืฉืืืื ืืืืื ืขืืืจ ืื ืืืื;
- ืืชืืกืฃ ืืืืฉื ืืืื ื ื ืชืื ืขืื.
ืืื ืืืชืืืจ ืขื ืืืกืจ ืืฆืืืืช
ืกืคืกืื ืืืืงื ืืื ื ืืืืืืืืื, ืืืืืง ืืื ืืืืืงืืช ืืืืืืืืืืช ืขืฆืื. ืืื ืื ืืคืชืืข ืฉืืฉ ืื ื ืืกืคืจ ืืืื ืื ืคืืืืื. ืื ืืืฆืื
ืืืืื ืืืืืจืช ืืืืงืืช ืืืืืืืืืช:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
โฆ.
<rerunFailingTestsCount>2</rerunFailingTestsCount>
โฆ.
</configuration>
</plugin>
ืื ืืืคืขืื: mvn โฆ -Dsurefire.rerunFailingTestsCount=2 โฆ
ืืืคืฉืจืืช, ืืืืจ ืืคืฉืจืืืืช ืฉื Maven ืขืืืจ ืกืงืจืืคื PowerShell (PS1):
Set-Item Env:MAVEN_OPTS "-Dfile.encoding=UTF-8 -Dsurefire.rerunFailingTestsCount=2"
ืืชืจืื ืืช:
- ืืื ืฆืืจื ืืืืื ืืื ืื ืืชืื ืืืื ืื ืืฆืื ืืืฉืจ ืืื ืงืืจืก;
- ื ืืชื ืืืงื ืขื ืืขืืืช ืืฆืืืืช ืกืคืกื ืืืืืงื.
ืืกืจืื ืืช:
- ื ืืชื ืืคืกืคืก ืคืืืื ืฆืคืื;
- ืืื ืืจืืฆื ืืื.
ืืืืงืืช ืืงืืืืืช ืขื ืกืคืจืืืช ืืืืคืคืื 4
ืืกืคืจ ืืืืื ืื ืืื ืืื ืืื. ืฉืื ืืฉืื ื ืืืืืฅ ืืช ืืจืืฆืืช. ืื ืืกืฃ, ืจืฆืืชื ืืฉืื ืืื ืฉืืืชืจ ืืืืงืืช ืืฆืื ืืจ ืืจืืืช ืืืคืืืงืฆืื. ืืืืจื ืืงืจืืื ืืื ืฉืืืจ ืืจืฆืื ืืงื ืืืชืจ ืืื ืืื ืืืฉืจ ืจืืฆื ืืืงืืื ืืืืฆืขืืช ืชืืกืฃ Maven.
ืืืืชื ืืื, Cucumber 4 ืืืจ ืฉืืืจืจ, ืื ืืืืื ื ืืฉืืชื ืืช ืืืืื ืืืจืกื ืื. ืืืขืจืืช ืืฉืืจืืจ ืืืืื ืื ื ืืฉืงื ืืงืืืื ืืจืืช ืืฉืจืฉืืจ. ืชืืืืจืืืช ืื ืฆืจืื ืืืืืช:
- ืืืืืฅ ืืฉืืขืืชืืช ืืช ืืคืขืืช ืืืืืงืืช ืืืืืืืืืืช ืขื ืืื ืืืืืช ืืกืคืจ ืืฉืจืฉืืจืื;
- ืืืกื ืืช ืืืืื ืืืื ืืืฆืืจืช ืจืฆืื ืขืืืจ ืื ืืืืงื ืืืืืืืืช.
ืืืคืืืืืืฆืื ืฉื ืืืกืืจืช ืขืืืจ ืืืืงืืช ืืืืืืืืืช ืขื ืจืืืื ืืืืืืช ืืชืืจืจื ืื ืื ืื ืงืฉื. Cucumber 4 ืืจืืฅ ืื ืืืืงื ืื ืคืจื ืขื ืฉืจืฉืืจ ืืืขืืื ืืชืืืืชื ืืขื ืกืืคื, ืื ืฉืืื ืืืจืื ืกืืืืื ื ืคืืฆืื ืคืฉืื ืืืืจื ืืืฉืชื ื ThreadLocal.
ืืืืจ ืืขืืงืจื ืืขืช ืืืจื ืืืืฆืขืืช ืืื Refactoring ืฉื Idea ืืื ืืืืืง ืืช ืืืงืืืืช ืฉืืื ืืืฉืชื ื ืืืฉืืื (ืืืืืื, ืืืืงืช null). ืื ืืกืฃ, ืขืืื ืืืืกืืฃ ืืช ืืชืืกืฃ Allure ืืืขืจืช ืืืืชื Junit Runner.
ืืืืื ืืืืืจืช ืืืืงืืช ืืืืืืืืืช:
<profile>
<id>parallel</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<useFile>false</useFile>
<testFailureIgnore>false</testFailureIgnore>
<parallel>methods</parallel>
<threadCount>6</threadCount>
<perCoreThreadCount>true</perCoreThreadCount>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
ืืืืื ืืืื Allure (ืืืืืงื ืืื ืื ืืฆืืื, 5 ืฉืืืืจืื ืืืืจืื)
ืขืืืก ืจืฅ ืืืืื ืืืืงืืช (8 ืืืืืช, 8 GB RAM, 24 ืคืชืืืื)
ืืชืจืื ืืช:
- ืฆืจืืืช ืืฉืืืื ื ืืืื;
- ืชืืืื ืืงืืืืช ืืืืคืคืื - ืืื ืฆืืจื ืืืืื ื ืืกืคืื;
- ืืืืืืช ืืืจืืฅ ืืืชืจ ื-6 ืคืชืืืื ืืื ืืืืช ืืขืื.
ืืกืจืื ืืช:
- ืขืืื ืืืืื ืฉืืงืื ืชืืื ืืืืฆืืข ืจืืืื ืืืืืื;
- ืกืฃ ืืื ืืกื ืขืืื.
Allure ืืืืื ืืืคื GitLab
ืืืืจ ืฉืืื ืกื ื ืืืฆืืข ืืจืืื-ืคืชืื, ืืชืืื ื ืืืฉืงืืข ืืจืื ืืืชืจ ืืื ืื ืืชืื ืืืืืช. ืืืืชื ืืื, ืืืื ื ืฆืจืืืื ืืืขืืืช ืื ืืื ืืืคืฅ ื- GitLab, ืืื ืืืืจืื ืืืชื ืืืคืจืืง ืืืชื. ืื ืื ืืืื ื ืื ืืืืงื ืืจืื ืืื. ืืื ืืืฉืื ืืืจ ืจืืฆื ืืจืืืช ืืช ืืืื ืืขืฆืื, ืื ืืื ืืฆืืจื ืืืฆืข ืืช ืืืชื ืคืขืืืืช. ืจืฆืื ื ืืงืื ืคืืืืง ืืืจ ืืืชืจ, ืืืฆืื ื ืคืชืจืื - ืืคื GitLab. ืืืื ืชืืื ื ืืืื ืืช ืืืืื ื ืืืงืืคืกื ืืื ืืืจืกืืืช ืืืืจืื ืืช ืฉื GitLab. ืืืคืฉืจ ืื ืืคืจืืก ืืชืจืื ืกืืืืื ืืฉืจืช ืฉืื ืืืืฉืช ืืืืื ืืืืฆืขืืช ืงืืฉืืจ ืืฉืืจ.
ืื ืฆืืืืื ืืืกื ืฉื ืืืืืช Allure ืฆืืืื ืืืคื GitLab. ืกืงืจืืคื ืืคืจืืกืช ืืืื ืืืคื GitLab - ื-Windows PowerShell (ืืคื ื ืื ืขืืื ืืืคืขืื ืืืืงืืช ืืืืืืืืืช):
New-Item -ItemType directory -Path $testresulthistory | Out-Null
try {Invoke-WebRequest -Uri $hst -OutFile $outputhst}
Catch{echo "fail copy history"}
try {Invoke-WebRequest -Uri $hsttrend -OutFile $outputhsttrnd}
Catch{echo "fail copy history trend"}
mvn allure:report
#mvn assembly:single -PzipAllureReport
xcopy $buildlocationtargetsiteallure-maven-plugin* $buildlocationpublic /s /i /Y
ืืืชืืฆืื ืืื ืฉ
ืื, ืื ืืฉืืชื ืื ืืชื ืฆืจืืืื ืงืื ืืืื ืฉื Thread ืืืกืืจืช ืืืืืงื ืืืืืืืืืช ืฉื Cucumber, ืืขืช ืืชืฉืืื ืืจืืจื - ืขื Cucumber 4 ืงื ืืืืฉื ืืืชื, ืืืื ืืืืืื ืืฉืืขืืชืืช ืืช ืืกืคืจ ืืฉืจืฉืืจืื ืฉืืืคืขืื ืื ืืื ืืช. ืืฉืืื ืื ืฉื ืืคืขืืช ืืืืงืืช, ืืฉืืื ืืืคืืช ืืขืช ืืืื ืืืืฆืืขืื ืฉื ืืืืื ื ืขื ืกืื ืืืื ืืกืคืกื ืืืืืงื.
ืืชืจืืื ืืจืื ืฉืืคืขืืช ืืืืงืืช ืืืืืืืืืช ืขื ืฉืจืฉืืจืื ืืืคืฉืจืช ืื ืืืคืืืช ืืช ืฆืจืืืช ืืืฉืืืื ืืืื ืืืื ืขื ืืืืฆืืขืื ืืืืืื ืืืืชืจ. ืืคื ืฉื ืืชื ืืจืืืช ืืืืจืคืื, ืืืคืืช ืืืืื ืืื ื ืืืืื ืืชืืืฆื ืืืื ืืืืื ื ืืืฆืืขืื. ืขื ืืืช, ืืฆืืื ื ืืืืกืืฃ ืืืชืจ ื-2 ืืืืงืืช ืืืืืืืืืช ืืื ืืืช ืืืคืืืงืฆืื, ืฉืืคืืื ืขื 200 ืฉืืืืจืื ืืืืจืื ืคืืขืืื ืชืื ื-5 ืืงืืช. ืื ืืืคืฉืจ ืืงืื ืืื ืืฉืื ืืืืจ, ืืืืืืช ืืฆืืจื ืืืฆืข ืฉืื ืืืื ืืืืืืจ ืขื ืืืืื ืฉืื.
ืืงืืจ: www.habr.com