יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB

הצוות שלנו יוצר צינורות אוטומטיים לחלוטין לפריסת גרסאות אפליקציות חדשות לסביבת הייצור. באופן טבעי, זה דורש בדיקות פונקציונליות אוטומטיות. להלן סיפור כיצד, החל מבדיקות חד-הליכיות על מכונה מקומית, התפתחנו להרצת בדיקות אוטומטיות מרובות-הליכיות ב-Selenoid בצינור הבנייה עם דיווחי Allure בדפי GitLab. בסופו של דבר, יצרנו כלי אוטומציה רב עוצמה שצוותים עתידיים יוכלו להשתמש בו.

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB

מאיפה התחלנו?

כדי ליישם בדיקות אוטומטיות ולשלב אותן בצנרת, היינו זקוקים למסגרת אוטומציה שניתן לשנות באופן גמיש כדי להתאים לצרכים שלנו. באופן אידיאלי, רצינו סטנדרט אחיד למנוע הבדיקות האוטומטיות, המותאם לשילוב בדיקות אוטומטיות בצנרת. בחרנו את הטכנולוגיות הבאות ליישום:

  • ג'אווה,
  • מייבן,
  • סֵלֶנִיוּם,
  • מלפפון+ג'וניט 4,
  • קֶסֶם,
  • GitLab.

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB

למה דווקא הסט הזה? ג'אווה היא אחת השפות הפופולריות ביותר לבדיקות אוטומטיות, וכל חברי הצוות בקיאים בה. סלניום הייתה בחירה מובנת מאליה. Cucumber, בין היתר, היה אמור להגביר את האמון בתוצאות בדיקות אוטומטיות בקרב הצוותים המבצעים בדיקות ידניות.

בדיקות חד-הליך

כדי להימנע מהמצאת הגלגל מחדש, ביססנו את המסגרת על פיתוחים ממאגרי GitHub שונים והתאמנו אותם לצרכים שלנו. יצרנו מאגר עבור הספרייה הראשית שהכיל את מסגרת הבדיקות האוטומטיות המרכזית ומאגר עם דוגמת זהב המיישמת בדיקות אוטומטיות על הליבה שלנו. כל צוות היה צריך לקחת את תמונת הזהב ולפתח בה בדיקות, תוך התאמתן לפרויקט שלו. פרסנו אותה במאגר GitLab-CI, שם הגדרנו:

  • השקות יומיות של כל הבדיקות האוטומטיות הכתובות עבור כל פרויקט;
  • פועל בצינור הבנייה.

בתחילה, היו רק כמה בדיקות, והן בוצעו ב-thread יחיד. ביצוע ב-single-threaded על גבי תוכנית ה-GitLab Windows התאים לנו בצורה מושלמת: הבדיקות העמיסו מעט מאוד על מערכת הבדיקה וכמעט ולא צרכו משאבים.

עם הזמן, מספר הבדיקות האוטומטיות גדל, והתחלנו לשקול להריץ אותן במקביל כאשר ריצה מלאה החלה להימשך כשלוש שעות. כמו כן צצו בעיות נוספות:

  • לא יכולנו לוודא שהבדיקות יציבות;
  • בדיקות שבוצעו מספר פעמים ברצף על מכונה מקומית נכשלו לעיתים ב-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>

 יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB
דוגמה לדוח Allure

 יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB
עומס על הרץ במהלך הבדיקות (8 ליבות, 8 ג'יגה-בייט זיכרון RAM, הליך משנה אחד)
 
יתרונות של בדיקות חד-הליך:

  • קל להתקנה ולהפעלה;
  • ריצות CI כמעט ואינן שונות מריצות מקומיות;
  • מבחנים אינם משפיעים זה על זה;
  • דרישות משאבי רצים מינימליות.

חסרונות של בדיקות חד-הליך:

  • לוקח זמן רב מאוד להשלמה;
  • ייצוב ארוך טווח של בדיקות;
  • שימוש לא יעיל במשאבי רצים, ניצול נמוך במיוחד.

בדיקות על מזלגות JVM

מכיוון שלא דאגנו לקוד בטוח-הליך בעת יישום המסגרת הבסיסית, הדרך הברורה ביותר להריץ אותה במקביל הייתה תוסף מקבילי של cucumber-jvm עבור Maven. התוסף קל להתקנה, אך לצורך פעולה מקבילה תקינה, יש להריץ בדיקות אוטומטיות בדפדפנים נפרדים. לא היה מה לעשות, אז הייתי צריך להשתמש ב-Selenoid.

שרת ה-Selenoid נפרס על מכונה עם 32 ליבות ו-24 ג'יגה-בייט של זיכרון RAM. המגבלה נקבעה ל-48 דפדפנים - 1,5 הליכים לליבה וכ-400 מגה-בייט של זיכרון RAM. כתוצאה מכך, זמן הבדיקה קוצר משלוש שעות ל-40 דקות. האצת הריצות עזרה לפתור את בעיית הייצוב: כעת יכולנו להריץ במהירות בדיקות אוטומטיות חדשות 20-30 פעמים עד שהיינו בטוחים שהן פועלות בצורה אמינה.
החיסרון הראשון של הפתרון היה ניצול משאבים גבוה של רצים עם מספר קטן של הליכים מקבילים: על 4 ליבות ו-8 ג'יגה-בייט של זיכרון RAM, הבדיקות רצו ביציבות עם לא יותר מ-6 הליכים. החיסרון השני: התוסף מייצר מחלקות רצים עבור כל תרחיש, ללא קשר למספרן.

חשוב! אין להעביר משתנה עם תגיות קו ארגומנט, למשל, כמו זה:

<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine>
…
Mvn –DTAGS="@smoke"

אם תעבירו את התג בדרך זו, התוסף ייצור רצים (runners) עבור כל הבדיקות, כלומר, הוא ינסה להריץ את כל הבדיקות, לדלג עליהן מיד לאחר ההשקה וליצור מספר פיצולי 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>

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTB
דוגמה לדוח Allure (הבדיקה הכי לא יציבה, 4 שידורים חוזרים)

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTBעומס על הרץ במהלך הבדיקות (8 ליבות, 8 ג'יגה-בייט זיכרון RAM, 12 הליכים)
 
יתרונות:

  • התקנה קלה - פשוט הוסיפו תוסף;
  • היכולת לבצע מספר רב של בדיקות בו זמנית;
  • האצת ייצוב הבדיקה הודות לנקודה 1. 

חסרונות:

  • נדרשות מספר מערכות הפעלה/מכולות;
  • צריכת משאבים גבוהה לכל מזלג;
  • התוסף הוצא משימוש ואינו נתמך עוד. 

איך להתגבר על חוסר יציבות 

מכונות בדיקה אינן מושלמות, בדיוק כמו בדיקות אוטומטיות עצמן. אין זה מפתיע שפיתחנו מספר בדיקות לא יציבות. לעזרתנו הגיעו תוסף מייבן סורפייר, אשר תומך בהפעלה מחדש של בדיקות שנכשלו ישירות מהקופסה. עליך לעדכן את התוסף לגרסה 2.21 לפחות ולהוסיף שורה אחת המציינת את מספר ההפעלות מחדש לקובץ pom או להעביר אותה כארגומנט ל-Maven.

דוגמה להגדרת בדיקות אוטומטיות:

   	
<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"

יתרונות:

  • אין צורך לבזבז זמן על ניתוח בדיקה לא יציבה כשהיא קורסת;
  • ניתן להחליק את בעיות היציבות של ספסל הבדיקה.

חסרונות:

  • ניתן להחמיץ פגמים צפים;
  • זמן הריצה גדל.

בדיקה מקבילה עם Cucumber 4

מספר הבדיקות גדל מדי יום. שוב התחלנו לחשוב על האצת הבדיקות. כמו כן, רצינו לשלב כמה שיותר בדיקות בצנרת הבנייה של האפליקציה. גורם קריטי היה זמן יצירת הרצים הארוך מדי בעת הרצתן במקביל באמצעות תוסף Maven.

באותו זמן, Cucumber 4 כבר שוחרר, אז החלטנו לכתוב מחדש את הליבה עבור גרסה זו. הערות הגרסה הבטיחו ביצוע מקביל ברמת השרשור. בתיאוריה, זה היה:

  • להאיץ משמעותית את ביצוע הבדיקות האוטומטיות על ידי הגדלת מספר השלבים (threads);
  • לחסל את הזמן שבוזבזים על יצירת רצים עבור כל בדיקה אוטומטית.

אופטימיזציה של המסגרת עבור בדיקות אוטומטיות מרובות-הליכים התבררה כפשוטה יחסית. Cucumber 4 מריץ כל בדיקה בנפרד ב-thread ייעודי מתחילתה ועד סופה, כך שכמה משתנים סטטיים נפוצים פשוט הומרו למשתני ThreadLocal. 
המפתח להמרה באמצעות שחזור רעיונות הוא לבדוק את המקומות שבהם התרחשו השוואות משתנים (לדוגמה, בדיקות 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>

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTBדוגמה לדוח Allure (הבדיקה הכי לא יציבה, 5 שידורים חוזרים)

יישום, קנה מידה: ניסיון בשימוש בבדיקות אוטומטיות ב-VTBעומס על הרץ במהלך הבדיקות (8 ליבות, 8 ג'יגה-בייט זיכרון RAM, 24 הליכים)

יתרונות:

  • צריכת משאבים נמוכה;
  • תמיכה מקורית מ-Cucumber - אין צורך בכלים נוספים;
  • היכולת להריץ יותר מ-6 נימים לכל ליבת מעבד.

חסרונות:

  • עליך לוודא שהקוד תומך בביצוע מרובה הליכים;
  • סף הכניסה עולה.

דוחות Allure בדפי GitLab

לאחר יישום השקה מרובת-הליכי משנה, התחלנו להשקיע זמן רב יותר בניתוח דוחות. בשלב זה, היינו צריכים להעלות כל דוח כארטיפקט ל-GitLab, ואז להוריד ולפתוח אותו. זה היה לא נוח וגזל זמן. ואם מישהו אחר רצה לצפות בדוח, הוא היה צריך לעשות את אותו הדבר. רצינו לקבל משוב מהר יותר, ומצאנו פתרון: GitLab Pages. תכונה מובנית זו, הזמינה ישירות מהקופסה בכל הגרסאות האחרונות של 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-safe) במסגרת הבדיקות האוטומטית של Cucumber, התשובה ברורה כעת: עם Cucumber 4, הוא קל ליישום, מה שמגדיל משמעותית את מספר ה-threads שניתן להריץ בו זמנית. בשיטה זו של הרצת בדיקות, ביצועי מכונת ה-Selenoid ומערך הבדיקה הופכים לדאגה.

הניסיון הראה כי הרצת בדיקות אוטומטיות על גבי תהליכים ממזערת את צריכת המשאבים תוך מקסום הביצועים. כפי שמראים הגרפים, הכפלת מספר התהליכים אינה מביאה לעלייה מקבילה במהירות ביצוע בדיקות הביצועים. אף על פי כן, הצלחנו להוסיף למעלה מ-200 בדיקות אוטומטיות לבניית האפליקציה, אשר, אפילו עם חמש הרצות חוזרות, רצות בכ-24 דקות. זה מאפשר לנו לקבל מהן משוב במהירות, ובמידת הצורך לבצע התאמות ולחזור על התהליך.

מקור: www.habr.com

הוספת תגובה