แผนกของเราสร้างไปป์ไลน์อัตโนมัติเต็มรูปแบบสำหรับการเปิดตัวแอปพลิเคชันเวอร์ชันใหม่ในสภาพแวดล้อมการผลิต แน่นอนว่าต้องมีการทดสอบการทำงานแบบอัตโนมัติ ด้านล่างเป็นเรื่องราวเกี่ยวกับวิธีการที่เริ่มต้นด้วยการทดสอบแบบเธรดเดียวบนเครื่องท้องถิ่น เรามาถึงจุดของการทดสอบอัตโนมัติแบบมัลติเธรดที่ทำงานบน Selenoid ในไปป์ไลน์การสร้างด้วยรายงาน Allure บนหน้า GitLab และในที่สุดก็ได้รับเครื่องมืออัตโนมัติที่ยอดเยี่ยม ที่คนในอนาคตสามารถใช้ทีมได้
เราเริ่มต้นที่ไหน?
ในการใช้การทดสอบอัตโนมัติและรวมเข้ากับไปป์ไลน์ เราจำเป็นต้องมีเฟรมเวิร์กการทำงานอัตโนมัติที่สามารถเปลี่ยนแปลงได้อย่างยืดหยุ่นเพื่อให้เหมาะกับความต้องการของเรา ตามหลักการแล้ว ฉันอยากได้มาตรฐานเดียวสำหรับกลไกการทดสอบอัตโนมัติ ซึ่งปรับให้เหมาะกับการฝังการทดสอบอัตโนมัติลงในไปป์ไลน์ สำหรับการนำไปใช้งาน เราเลือกเทคโนโลยีดังต่อไปนี้:
- ชวา
- มาเวน
- ซีลีเนียม,
- แตงกวา+จูนิท 4,
- จูงใจ,
- GitLab
ทำไมต้องเป็นชุดนี้โดยเฉพาะ? Java เป็นหนึ่งในภาษายอดนิยมสำหรับการทดสอบอัตโนมัติ และสมาชิกในทีมทุกคนก็พูดได้ ซีลีเนียมเป็นวิธีแก้ปัญหาที่ชัดเจน เหนือสิ่งอื่นใด แตงกวาควรจะเพิ่มความมั่นใจในผลลัพธ์ของการทดสอบอัตโนมัติในส่วนของแผนกที่เกี่ยวข้องกับการทดสอบด้วยตนเอง
การทดสอบแบบเธรดเดี่ยว
เพื่อไม่ให้สร้างวงล้อขึ้นมาใหม่ เราได้นำการพัฒนาจากแหล่งเก็บข้อมูลต่างๆ บน GitHub มาเป็นพื้นฐานสำหรับเฟรมเวิร์กและนำมาปรับใช้สำหรับตัวเราเอง เราสร้างพื้นที่เก็บข้อมูลสำหรับไลบรารีหลักด้วยแกนหลักของเฟรมเวิร์กการทดสอบอัตโนมัติ และพื้นที่เก็บข้อมูลพร้อมตัวอย่าง Gold ของการนำการทดสอบอัตโนมัติไปใช้กับแกนหลักของเรา แต่ละทีมต้องใช้อิมเมจระดับโกลด์และพัฒนาการทดสอบในนั้น และปรับให้เข้ากับโปรเจ็กต์ของพวกเขา เราปรับใช้กับธนาคาร GitLab-CI ซึ่งเรากำหนดค่าไว้:
- การดำเนินการทดสอบอัตโนมัติที่เป็นลายลักษณ์อักษรทั้งหมดในแต่ละวันสำหรับแต่ละโครงการ
- เปิดตัวในไปป์ไลน์การสร้าง
ในตอนแรกมีการทดสอบไม่กี่ครั้ง และดำเนินการในคราวเดียว การรันแบบเธรดเดียวบน Windows runner 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>
ตัวอย่างรายงาน Allure
โหลดรันเนอร์ระหว่างการทดสอบ (8 คอร์, RAM 8 GB, 1 เธรด)
ข้อดีของการทดสอบแบบเธรดเดียว:
- ติดตั้งและใช้งานได้ง่าย
- การเปิดตัวใน CI นั้นแทบไม่ต่างจากการเปิดตัวในท้องถิ่น
- การทดสอบไม่ส่งผลกระทบต่อกัน
- ข้อกำหนดขั้นต่ำสำหรับทรัพยากรนักวิ่ง
ข้อเสียของการทดสอบแบบเธรดเดียว:
- ใช้เวลาดำเนินการนานมาก
- ความเสถียรของการทดสอบที่ยาวนาน
- การใช้ทรัพยากรนักวิ่งอย่างไม่มีประสิทธิภาพ การใช้งานต่ำมาก
การทดสอบบนส้อม JVM
เนื่องจากเราไม่ได้ดูแลโค้ดที่ปลอดภัยสำหรับเธรดเมื่อใช้เฟรมเวิร์กพื้นฐาน วิธีที่ชัดเจนที่สุดในการทำงานแบบขนานก็คือ
เซิร์ฟเวอร์ Selenoid เปิดตัวบนเครื่องที่มี 32 คอร์และ RAM 24 GB ขีดจำกัดถูกกำหนดไว้ที่ 48 เบราว์เซอร์ - 1,5 เธรดต่อคอร์ และ RAM ประมาณ 400 MB ส่งผลให้เวลาในการทดสอบลดลงจาก 40 ชั่วโมงเหลือ 20 นาที การเร่งความเร็วในการวิ่งช่วยแก้ปัญหาเรื่องความเสถียร: ตอนนี้เราสามารถรันการทดสอบอัตโนมัติใหม่ได้อย่างรวดเร็ว 30–XNUMX ครั้งจนกว่าเราจะแน่ใจว่าการทดสอบนั้นทำงานได้อย่างน่าเชื่อถือ
ข้อเสียเปรียบประการแรกของโซลูชันคือการใช้ประโยชน์ทรัพยากรนักวิ่งในระดับสูงโดยมีเธรดคู่ขนานจำนวนน้อย: บน 4 คอร์และ RAM ขนาด 8 GB การทดสอบทำงานได้อย่างเสถียรโดยใช้เธรดไม่เกิน 6 เธรด ข้อเสียประการที่สอง: ปลั๊กอินสร้างคลาสนักวิ่งสำหรับแต่ละสถานการณ์ ไม่ว่าจะเปิดตัวกี่คลาสก็ตาม
ที่สำคัญ! อย่าส่งตัวแปรที่มีแท็กไปให้ หาเรื่องLineตัวอย่างเช่นเช่นนี้:
<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine>
…
Mvn –DTAGS="@smoke"
หากคุณส่งแท็กด้วยวิธีนี้ ปลั๊กอินจะสร้างนักวิ่งสำหรับการทดสอบทั้งหมด กล่าวคือ จะพยายามเรียกใช้การทดสอบทั้งหมด โดยข้ามการทดสอบทันทีหลังจากเปิดตัว และสร้าง JVM forks จำนวนมาก
เป็นการถูกต้องที่จะโยนตัวแปรที่มีแท็กเข้าไป แท็ก ในการตั้งค่าปลั๊กอิน ดูตัวอย่างด้านล่าง วิธีอื่นที่เราทดสอบมีปัญหาในการเชื่อมต่อปลั๊กอิน 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 คอร์, RAM 8 GB, 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"
จุดเด่น:
- ไม่จำเป็นต้องเสียเวลาวิเคราะห์การทดสอบที่ไม่เสถียรเมื่อเกิดปัญหา
- ปัญหาความเสถียรของม้านั่งทดสอบสามารถบรรเทาลงได้
จุดด้อย:
- ข้อบกพร่องลอยตัวสามารถพลาดได้
- เวลาทำงานเพิ่มขึ้น
การทดสอบแบบขนานกับไลบรารี Cucumber 4
จำนวนการทดสอบเพิ่มขึ้นทุกวัน เราคิดอีกครั้งว่าจะเร่งความเร็วในการวิ่ง นอกจากนี้ ฉันต้องการรวมการทดสอบเข้ากับไปป์ไลน์การประกอบแอปพลิเคชันให้ได้มากที่สุด ปัจจัยสำคัญคือการสร้างนักวิ่งใช้เวลานานเกินไปเมื่อทำงานแบบขนานโดยใช้ปลั๊กอิน Maven
ในเวลานั้น Cucumber 4 เปิดตัวแล้ว ดังนั้นเราจึงตัดสินใจเขียนเคอร์เนลใหม่สำหรับเวอร์ชันนี้ ในบันทึกประจำรุ่น เราสัญญาว่าจะเปิดตัวแบบขนานที่ระดับเธรด ตามทฤษฎีแล้วสิ่งนี้ควรเป็น:
- เพิ่มความเร็วในการรันการทดสอบอัตโนมัติอย่างมากโดยการเพิ่มจำนวนเธรด
- ลดการเสียเวลาในการสร้างนักวิ่งสำหรับการทดสอบอัตโนมัติแต่ละครั้ง
การเพิ่มประสิทธิภาพเฟรมเวิร์กสำหรับการทดสอบอัตโนมัติแบบมัลติเธรดนั้นไม่ใช่เรื่องยาก Cucumber 4 รันการทดสอบแต่ละครั้งบนเธรดเฉพาะตั้งแต่ต้นจนจบ ดังนั้นค่าคงที่ทั่วไปบางอย่างจึงถูกแปลงเป็นตัวแปร ThreadLocal
สิ่งสำคัญเมื่อทำการแปลงโดยใช้เครื่องมือการปรับโครงสร้างใหม่ของ Idea คือการตรวจสอบตำแหน่งที่มีการเปรียบเทียบตัวแปร (เช่น การตรวจสอบค่าว่าง) นอกจากนี้ คุณต้องเพิ่มปลั๊กอิน 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 คอร์, RAM 8 GB, 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
ผลลัพธ์คืออะไร
ดังนั้น หากคุณกำลังคิดว่าคุณต้องการโค้ดที่ปลอดภัยสำหรับเธรดในเฟรมเวิร์กการทดสอบอัตโนมัติของ Cucumber หรือไม่ ตอนนี้คำตอบก็ชัดเจนแล้ว ด้วย Cucumber 4 ทำให้ง่ายต่อการใช้งาน จึงทำให้จำนวนเธรดที่เปิดพร้อมกันเพิ่มขึ้นอย่างมาก ด้วยวิธีการทดสอบการทำงานนี้ คำถามจึงกลายเป็นเกี่ยวกับประสิทธิภาพของเครื่องจักรที่มีเซลีนอยด์และแท่นทดสอบ
การปฏิบัติแสดงให้เห็นว่าการรันการทดสอบอัตโนมัติบนเธรดช่วยให้คุณลดการใช้ทรัพยากรให้เหลือน้อยที่สุดด้วยประสิทธิภาพที่ดีที่สุด ดังที่เห็นได้จากกราฟ การเพิ่มเธรดสองเท่าไม่ได้นำไปสู่การเร่งความเร็วที่คล้ายคลึงกันในการทดสอบประสิทธิภาพ อย่างไรก็ตาม เราสามารถเพิ่มการทดสอบอัตโนมัติมากกว่า 2 รายการให้กับบิลด์แอปพลิเคชัน ซึ่งแม้จะรันซ้ำ 200 ครั้งในเวลาประมาณ 5 นาที วิธีนี้ช่วยให้คุณได้รับการตอบรับอย่างรวดเร็วจากพวกเขา และหากจำเป็น ให้คุณทำการเปลี่ยนแปลงและทำซ้ำขั้นตอนอีกครั้ง
ที่มา: will.com