كيفية توليد تقرير غطاء التعليمات باستخدام ملحق JaCoCo-Maven

تغطية الكود هي مقياس جودة البرمجيات الشائع الاستخدام خلال عملية التطوير الذي يتيح لك تحديد درجة تغطية الكود الذي تم اختباره (أو تنفيذه). لتحقيق تغطية الكود المثالية، من الضروري أن يختبر تنفيذ الاختبارات (أو سلالم الاختبار) نسبة كبيرة من الكود المُنفذ.

هناك عدد من أدوات تغطية الكود لللغات مثل Java، C#، JavaScript، إلخ. استخدام أفضل أداة تغطية الكود مناسبة هو أمر حيوي لفهم نسبة الكود المُختبر واتخاذ الإجراءات المناسبة لضمان تحقيق التغطية المثالية.

لاختبار الكود بشكل مثالي، تستخدم العديد من الشركات ملحق JaCoCo-Maven الذي يساعد في توليد تقارير تغطية الكود المفصلة. ملحق JaCoCo-Maven هو مكتبة تغطية الكود مجانية لمشاريع Java. إنها تعتمد على دراسة مكتبات التكامل الحالية التي أنشأها فريق EclEmma. إلى حد كبير، تعطي تغطية الكود نظرة سريعة على جودة المنتج لأنه كلما زادت التغطية، قلت إحتمالات دخول الكود غير المُختبر في دورة الإصدار.

في هذا المقال، سنتعرف أكثر على ملحق JaCoCo-Maven وكيفية تنفيذ هذا الملحق باستخدام Maven. سنقوم أيضًا بتكامل مشروع Maven وتوليد تقرير تغطية الكود المفصل للاختبارات عن طريق إجراء Selenium.

ما هي تغطية الكود؟

في تطوير البرمجيات، تغطية الكود هي مقياس يستخدم لوصف درجة التنفيذ لشفرة المصدر لتطبيق معين عندما يتم تنفيذ مجموعة اختبار. يتم إنشاء تقرير لمشاهدة وتحليل تغطية الكود لتطبيق برمجي. يمكن بعدها استخدام تقرير تغطية الكود لضمان جودة الكود.

يُستخدم مُلحق JaCoCo-Maven لإنشاء تقارير تغطية الكود. يتم تنفيذ المزيد من التعليمات البرمجية في الكود المصدر ذي التغطية الكبيرة خلال الاختبارات. على سبيل المثال، إذا كانت البرمجيات التي تختبرها تحتوي على 100 سطر من الكود وكان عدد سطور الكود المصدقة في البرنامج 90، فإن نسبة تغطية الكود لتطبيق البرنامج الخاص بك ستكون 90٪.

مزايا تغطية الكود

تعد تغطية الكود مقياسًا مفيدًا للمطورين والمختبرين ومهندسي الجودة. إليك بعض المزايا البارزة لتغطية الكود:

  • توفر تقارير تغطية الكود رؤى مفيدة في الكشف عن الكود الميت والقضاء عليه. يمكن تجنب ذلك من خلال اتباع أفضل الممارسات التنفيذية، والتي بدورها تؤدي إلى تحسين صيانة الكود وجودة المنتج.
  • يمكن لضمان الجودة تحديد الكود الذي لم يتم تغطيته باستخدام تنفيذ الاختبار.
  • يمكن للمطورين إنهاء عملية تطوير البرمجيات بشكل أسرع، مما يزيد من مرونتهم وكفاءتهم وكفاءتهم. هذا يؤدي إلى تقليل وقت السوق (TTM).

كما نعلم، تغطية الكود مهمة لكل منتج برمجي. الآن بعد أن قمنا بمراجعة سريعة حول الجوانب الأساسية لتغطية الكود، دعونا نتعمق في الموضوع الأساسي لدينا، أي إنشاء تقارير تغطية الكود باستخدام مُلحق JaCoCo-Maven.

ما هو مُلحق JaCoCo-Maven؟

مُلحق JaCoCo-Maven (اختصار لـ Java Code Coverage) هو أداة لتغطية الكود مفتوحة المصدر للجافا. يخلق تقارير تغطية الكود ويدمج بشكل جيد مع بيئات التطوير المتكاملة (IDEs)، مثل بيئة تطوير Eclipse.

يتم تكامله أيضًا بسلاسة مع أدوات CI/CD (على سبيل المثال Jenkins، Circle CI ، إلخ) وأدوات إدارة المشاريع (على سبيل المثال، SonarQube، إلخ). إنه جزء من مؤسسة إكليبس وقد استبدل أداة كفاية التعليمات EclEmma في إكليبس.

كيف يعمل ملحق JaCoCo-Maven؟

  • يقوم ملحق JaCoCo-Maven بتشغيل التغطية عن طريق تحويل التعليمات البرمجية بلغة جافا عبر وكيل جاري التشغيل. ببساطة، تعلق هذا الوكيل بآلية تشغيل JVM (Java Virtual Machine) عند بدء التشغيل. يطلق على هذا الوكيل اسم وكيل JaCoCo. يبدأ التنفيذ الأول start-agent هذا وكيل JaCoCo جاري التشغيل.
  • كلما تم تحميل فئة، يمكن لـ JaCoCo تحويل الفئة بحيث يمكنه مشاهدة متى تم استدعاء الفئة وأي سطور (من التعليمات البرمجية) تم استدعاؤها خلال عملية الاختبار. من خلال تتبع هذا، يقوم بتجميع إحصائيات تغطية التعليمات البرمجية، وهو ما يتم على الفور خلال التنفيذ الثاني (أي generate-report).
  • بشكل افتراضي، يتم إنشاء الملف بمجرد انتهاء عمل JVM، ولكن من الممكن أيضًا تشغيل الوكيل في وضع الخادم. هذا يؤدي إلى تفريغ نتائج التقارير وإنشاء التقرير قبل الانتهاء. تظهر أدناه الداخليات لملحق JaCoCo:

  • يمكنك تحديد الأهداف والقواعد في تكوين ملحق JaCoCo-Maven. هذا يمنحك المرونة لتحديد الحدود ويساعد في التحقق من مقدار تغطية التعليمات البرمجية.
  • ملحق Maven-surefire هو ملحق Maven افتراضي. يقوم بتشغيل الاختبارات في JVM ويوفر تقارير التغطية. بينما يقوم ملحق JaCoCo بتحويل التعليمات البرمجية التي تم تنفيذها بواسطة ملحق (على سبيل المثال، ملحق Surefire). وبالتالي، من الممارسات الجيدة التحقق من تبعية ملحق maven-surefire.

لماذا يعد ملحق JaCoCo-Maven لطيفًا لتغطية الكود؟

ملحق JaCoCo-Maven مناسب لتغطية الكود بسبب الأسباب التالية:

  • عند العمل في أي مشروع، يفضل المطورون عادةً استخدام برامج التطوير الإنتراسية (IDEs) لأنها تسهل تجربة البرمجة والاختبار. يمكن تثبيت JaCoCo على برنامج تطوير الإنتراسية Eclipse تحت اسم EclEmma، من خلال تنزيل EclEmma من سوقته.
  • من السهل إضافة ملحق JaCoCo لجميع أنواع البناء، بما في ذلك ANT، Maven، وGradle. يمكن أيضًا دمجه مع أدوات CI/CD مثل Jenkins، Circle CI، وغيرها. هذا يجعله متعدد الاستخدامات للعديد من الحالات.
  • تقرير تغطية الكود الذي يولده JaCoCo هو ملف HTML بسيط ومفيد يمكن مشاهدته في أي متصفح أو IDE.
  • يوفر JaCoCo أيضًا تحسين الأداء عند التشغيل (أي أن جميع الصفحات تم تحسينها قبل تشغيل أي اختبارات).
  • تحليل تقرير أيضًا سهل للغاية، حيث يتم التعبير عنه بالألوان ويوفر النسبة المئوية الدقيقة لتغطية الكود.

كيفية إعداد ملحق JaCoCo مع Maven

للحصول على تقارير تغطية الكود في مشروع Maven، نحتاج أولاً إلى إعداد ملحق JaCoCo لهذا المشروع. من خلال دمج ملحق JaCoCo، يمكن مراجعة أثر تحليل تغطية الكود كتقرير HTML. يمكن تنزيل الإصدار الحالي من ملحق JaCoCo-Maven من مستودع MVN.

فيما يلي الخطوات لدمج ملحق JaCoCo مع مشروع Maven:

1. كل مشروع Maven يحتوي على ملف pom.xml، الذي يستخدم لتعريف جميع العوائق والملحقات. تم تعريف ملحق JaCoCo-Maven في نفس ملف POM.xml. الشفرة الإكس ميل لهذا هي:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
</plugin>

هذه هي الشفرة الإكس ميل الأساسية التي تم إضافتها تحت علامة البناء لتحديد ملحق JaCoCo في مشروع يعتمد على Maven. يمكننا تعزيز الوظيفة (مثل ذكر متى يجب توليد تقرير، إلخ) عن طريق تحديد الأهداف والقواعد في علامة التنفيذ.

2. بعد علامة الإصدار، نضيف علامة التنفيذ. تلك العلامة تعد الخصائص أو التنفيذ للإشارة إلى وكيل JaCoCo ويتم تمريره كحجة VM (في هذه الحالة، JVM).

3. لتشغيل اختبارات الوحدة البسيطة، ستعمل أهدافان محددتان في علامات التنفيذ بشكل جيد. الحد الأدنى هو إعداد أهداف prepare-agent و report.

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
        </execution>
    </executions>
 </plugin>


  • أهداف prepare-agent: أهداف prepare-agent تعد JaCoCo runtime agent لتسجيل بيانات التنفيذ. يسجل عدد الأسطر التي تم تنفيذها، والتحقق من الصحة، إلخ. بشكل افتراضي، يتم كتابة بيانات التنفيذ إلى الملف target/jacoco-ut.exec.
  • أهداف report: أهداف report تنشئ تقارير تغطية الكود من بيانات التنفيذ التي تم تسجيلها بواسطة JaCoCo runtime agent. نظرًا لأننا حددنا خاصية المرحلة، ستتم إنشاء التقارير بعد تجميع مرحلة الاختبار. بشكل افتراضي، يتم قراءة بيانات التنفيذ من الملف target/jacoco-ut.exec، ويتم كتابة تقرير تغطية الكود إلى الدليل target/site/jacoco/index.html.

4. لتشغيل اختبارات الوحدة البسيطة، يعمل التكوين أعلاه بشكل جيد. ومع ذلك، نحتاج إلى وضع قيود على تقارير تغطية الشفرة (على سبيل المثال، تحديد الدليل المستهدف، إلخ). يمكن القيام بذلك عبر تاج التكوين:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
            <configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
            </configuration>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
               <configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
               </configuration>
        </execution>
    </executions>
 </plugin>

تكوين التنفيذ الأول

وفقًا للكود أعلاه، يمكنك رؤية بعض العلامات، مثل destFile، إلخ، محددة. إليك وصف موجز للعلامات:

  • destFileعلامة: تُستخدم علامة destFile لتحديد المسار إلى الملف الذي يحتوي على بيانات التنفيذ.
  • propertyName-surefireArgLineعلامة: تحدد هذه العلامة اسم الخاصية التي تحتوي على إعدادات وكيل جاكوكو التشغيلي. كما تحدد خط الوساطة البرمجية فيما عدا عندما يتم تشغيل اختبارات الوحدة.

تكوين التنفيذ الثاني

وفقًا للكود أعلاه، يمكنك رؤية علامات مثل dataFile، إلخ، محددة. إليك وصف موجز للعلامات:

  • dataFileعلامة: تُستخدم علامة dataFile لتحديد المسار إلى الملف الذي يحتوي على بيانات التنفيذ.
  • outputDirectoryعلامة: تحدد هذه العلامة الدليل الناتج لتقارير تغطية الشفرة.

5. يمكننا أيضًا إضافة قواعد إلى علامة التكوين للتحقق من نسبة تغطية الشفرة. يمكن القيام بذلك كما هو موضح أدناه:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
            <configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
            </configuration>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
               <configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
               </configuration>
        </execution>
        <execution>
              <id>jacoco-check</id>
              <goals>
                <goal>check</goal>
              </goals>
              <configuration>
              	<rules>
                 	   <rule>
                    	<element>PACKAGE</element>
                    	<limits>
                      		<limit>
                        		<counter>LINE</counter>
                        		<value>COVEREDRATIO</value>
                        		<minimum>0.50</minimum>
                      		</limit>
                   	</limits>
                	   </rule>
            	      </rules>
             </configuration>
 	  </execution>
    </executions>
 </plugin>

تكوين التنفيذ الثالث

هنا يتم تحديد فحص هدف جديد. يتم ربط هدف jacoco:check بالتحقق من القاعدة المحددة. القاعدة تُعطى في علامة القاعدة. لديك المرونة لتحديد أكثر من قاعدة واحدة.

  • علامة عنصر: تحدد هذه العلامة العنصر الذي يجب تطبيق القاعدة عليه.
  • علامة الحد: تستخدم علامات مثل counter, value, minimum إلخ لتحديد نسبة التغطية البرمجية. يمكن استخدام أمر مثل mvn clean verify للتأكد مما إذا كانت القاعدة متبعة أم لا.

6. يمكن تحديد العديد من الأهداف والقواعد في تكوين ملف JaCoCo-Maven.

تقارير تغطية الكود باستخدام Maven وملف JaCoCo

في هذا القسم، سنوضح خطوات توليد تقرير تغطية الكود باستخدام ملف JaCoCo لـ Maven. الشرح يتم بأخذ موقف اختبار بسيط للغاية. لذا، فلنبدأ.

الشروط الأساسية

  1. Maven 3.0 أو أعلى: Maven هو أداة الإدارة وفهم المشروع. يمكنك تثبيت أحدث إصدار من موقع Apache Maven الرسمي.
  2. Java 1.5 أو أعلى: تحتاج للتأكد من تثبيت Java على جهازك. في حالة عدم تثبيت Java، يرجى تنزيل أحدث إصدار من موقع Java الرسمي.
  3. IDE Eclipse لمطوري Java: على الرغم من استخدام IDE المفضلة لديك، لكن في هذا العرض نستخدم IDE Eclipse.

خطوات لإنشاء مشروع Maven بسيط

  1. في IDE Eclipse، انتقل إلى ملف > جديد > مشروع Maven.

2. يظهر مربع حوار جديد. تأكد من تحديد مربع الاختيار “استخدام موقع المكتبة الافتراضي” وانقر على ” التالي.”

3. لاختيار النموذج في المشروع، اكتب org.apache.maven في مربع النص الموجود بجانب الفلتر. اختر maven-archetype-quickstart وانقر على ” التالي.”

4. الآن، يحدد ” معرف المجموعة” كـ com.example و” معرف الإنتاج” كـ jacoco-example. ” معرف الإنتاج” هو اسم مشروعنا. أخيرًا، انقر على زر ” انتهى.”

5. يمكنك رؤية هيكل الملفات والمجلدات للمشروع في ” مستكشف المشروع.”

كيفية تحديد ملحق JaCoCo Maven في POM.xml

1. افتح POM.xml، انتقل إلى العلامة. سنحدد ملحق JaCoCo-Maven في القسم الذي يسرد ملحقات Maven. فقط انسخ الكود التالي والصقه في العلامة المذكورة أعلاه:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
     <!--first execution : for preparing JaCoCo runtime agent-->
      <execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
      </execution>
     <!--second execution : for creating code coverage reports-->
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
        </execution>
    </executions>
 </plugin>

2. نظرًا لأننا نوضح توليد تقرير للاختبار الآلي الويب باستخدام JUnit، سنعلن أيضًا عن تبعية JUnit في POM.xml.

إليك المحتوى الكامل لـ POM.xml:

 

<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>


  <groupId>com.example</groupId>
  <artifactId>jacoco-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>

 <name>jacoco-example</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>


<!-- JUnit dependencies added to run test cases -->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>


  <build>
      <plugins>
        <!-- Maven plugin for Project Management -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.19.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>
                                  
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals><goal>prepare-agent</goal></goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals><goal>report</goal></goals>
                    </execution>
                </executions>
            </plugin>
      </plugins>
  </build> 
</project>

3. من داخل دليل المشروع، انتقل إلى ” حزمة كوم.مثال.جاكوكو_لامدا تست” الموجودة في src/main/java. قم بإنشاء فئة جديدة Java باسم LambdaTest.java. سنكتب دالة setUp() بسيطة فيها توفر القدرات المرغوبة من جهاز Selenium Grid.

 

package com.example.Jacoco_lambdatest;

import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LambdaTest {
	public static String username = "<LambdaTest_Username>";
	public static String accessKey = "<LambdaTest_AccessKey>";
	
  public static DesiredCapabilities setUp() throws Exception {
     DesiredCapabilities capabilities = new DesiredCapabilities();
      capabilities.setCapability("platform", "Windows 10");
	     capabilities.setCapability("browserName", "Chrome");
	     capabilities.setCapability("version", "87.0"); // If this cap isn't specified, it will just get the any available one
      capabilities.setCapability("resolution","1024x768");
      capabilities.setCapability("build", "First Test");
      capabilities.setCapability("name", "Sample Test");
      capabilities.setCapability("network", true); // To enable network logs
      capabilities.setCapability("visual", true); // To enable step by step screenshot
      capabilities.setCapability("video", true); // To enable video recording
      capabilities.setCapability("console", true); // To capture console logs
      return capabilities;
  }
}

إضافة حالات اختبار JUnit في المشروع

1. سنقوم بإنشاء حالة تحقق بسيطة باستخدام JUnit في AppTest.java. يتم توفير هذا افتراضيًا في المجلد src/test/java تحت اسم الحزمة com.example.jacoco_lambdatest.

 

package com.example.Jacoco_lambdatest;

import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import com.example.Jacoco_lambdatest.*;

public class AppTest {
	public static RemoteWebDriver driver;
	
	@Test
	public void testScript1() throws Exception {
		try {
	DesiredCapabilities capabilities = LambdaTest.setUp();
	String username =LambdaTest.username;
	String accessKey = LambdaTest.accessKey;
	RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);       driver.get("https://lambdatest.github.io/sample-todo-app/");
     driver.findElement(By.name("li1")).click();
	driver.findElement(By.name("li2")).click();		      driver.findElement(By.id("sampletodotext")).clear();		driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
	driver.findElement(By.id("addbutton")).click();
	driver.quit();					
	} catch (Exception e) {
		System.out.println(e.getMessage());
		}
	}
}

إنشاء تقارير تغطية الكود

1. انقر على زر “تشغيل ك” وقم بتحديد التكوين كـ Test مع Maven.

2. بدلاً من ذلك، يمكنك فتح الأمر في سطر الأوامر (Command Line)، انتقل إلى مجلد المشروع، وقم بتشغيل أمر Maven “mvn test”.

3. تشغيل اختبارات JUnit سيقوم تلقائيًا بتشغيل وكيل JaCoCo. سينشئ تقريرًا بتنسيق ثنائي في المجلد المستهدف، بالمسار target/jacoco.exec. لا يمكن تفسير ناتج jacoco.exec بمفردك، ولكن هناك أدوات مثل SonarQube والبرنامج التعليمي يمكنها تفسيره. كما أشرنا سابقًا، سيولد الهدف jacoco:report تقارير تغطية الكود قابلة للقراءة بصيغ شهيرة مثل HTML، CSV، و XML.

4. بمجرد نجاح البناء، انتقل إلى مجلد الهدف، ثم إلى الموقع > مجلد jacoco. يقع تقرير تغطية الكود (أي index.html) في المسار target/site/jacoco/index.html. يبدو التقرير هكذا:

5. يمكنك التبصر في المستوى الدقيق عن طريق النقر على com.example.jacoco_lambdatest>LambdaTest في التقرير.

6. بالنقر على وظائف محددة، ستحصل على نظرة تفصيلية أكثر في LambdaTest.java.

7. هنا سترى العديد من الماسات بألوان مختلفة مثل الأخضر والأصفر والأحمر. تُستخدم هذه المواصفات في التقرير لتمثيل أي سطر من الكود تم تنفيذه ومتى تم تنفيذه. سنتعرف على المزيد حول هذا في القسم التالي من تحليل التقرير. بهذا، لقد نجحت في إنشاء تقرير حول تغطية الكود عبر ملحق Jacoco لـ Maven.

تحليل تقرير تغطية الكود

تظهر تقرير تغطية الكود لدينا تغطية 94% للتعليمات وتغطية 100% للفروع، وهو درجة عالية لتغطية الكود. فيما بعد، سنحاول تحقيق درجة تغطية 100% من خلال إضافة المزيد من الاختبارات.

تشير التعليمات الـ 38 التي تظهرها JaCoCo في التقرير إلى تعليمات شفرة البايت بدلاً من تعليمات الشفرة الأصلية Java. تساعدك تقارير JaCoCo على تحليل بصري لتغطية الكود عن طريق استخدام الماسات بألوان للفروع وتمييز الألوان الخلفية للأسطر. توضيح موجز للماسات التي تراها في تقرير تغطية الكود أدناه:

  • الماس الأحمر; يشير إلى عدم ممارسة أي فروع خلال مرحلة الاختبار.
  • الماس الأصفر: يشير إلى أن الكود مغطى جزئياً (أي بعض الفروع لم يتم ممارستها).
  • الماس الأخضر: يشير إلى أن جميع الفروع ممارسة خلال الاختبار

ينطبق نفس رمز الألوان على تمييز الألوان الخلفية لتغطية الأسطر.

يوفر التقرير أساساً ثلاثة إحصائيات حاسمة:

  1. تغطية السطر: وهي تعكس مقدار تنفيذ الكود بناءً على عدد تعليمات شفرة Java البايت التي استدعتها الاختبارات.
  2. تغطية الفروع: يوضح هذا النسبة المئوية للفروع التي تم تنفيذها في الشفرة المصدر. وهذه شيء شائع في عبارات if/else أو switch.
  3. التعقيد الدوراني: يعكس هذا تعقيد الكود عبر عدد المسارات اللازمة لتغطية كل المسارات الممكنة في الكود. كما يشير أيضًا إلى عدد الحالات الاختبارية اللازمة لتنفيذها لتغطية الكود بأكمله. حيث لا يوجد switch أو عبارة في الكود، سيكون التعقيد الدوراني واحد؛ فقط مسار تنفيذ واحد يكفي لتغطية الكود بأكمله.

إدخال المزيد من الحالات الاختبارية لتحسين تغطية الكود

1. لتحقيق تغطية أفضل للكود، يجب إدخال اختبارات أكثر تختبر الكود الذي لم يتم تغطيته سابقًا من خلال تنفيذ الاختبار.

2. انتقل إلى AppTest.java في src/test/java لإضافة المزيد من الحالات الاختبارية.

3. ستبدو الحالات الاختبارية الجديدة المضافة إلى AppTest.java كما يلي:

 

@Test
	public void testScript2() throws Exception {
	    try {
	    DesiredCapabilities capabilities = LambdaTest.setUp();
	    String username = LambdaTest.username;
	    String accessKey = LambdaTest.accessKey;
	    RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);		 driver.get("https://lambdatest.github.io/sample-todo-app/");		    driver.findElement(By.name("li2")).click();
	    driver.findElement(By.name("li3")).click();
	   driver.findElement(By.id("sampletodotext")).clear();	driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add it to list");				driver.findElement(By.id("addbutton")).click();
					driver.quit();					
		} catch (Exception e) {
				System.out.println(e.getMessage());
			    }
			}
	

	@Test
	public void testScript3() throws Exception {
		try {
	    DesiredCapabilities capabilities = LambdaTest.setUp();
	    String username = LambdaTest.username;
	    String accessKey = LambdaTest.accessKey;
	    RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);			  driver.get("https://lambdatest.github.io/sample-todo-app/");		    driver.findElement(By.name("li4")).click();
	    driver.findElement(By.id("sampletodotext")).clear();	driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add  it!");
	  driver.findElement(By.id("addbutton")).click();
	  driver.quit();					
	} catch (Exception e) {
		System.out.println(e.getMessage());
			}
			}

4. لنقم بتشغيل تقرير Maven JaCoCo لنشر تقرير تغطية جديد.

5. JaCoCo يوفر طريقة بسيطة وسهلة لتتبع نتيجة تغطية الكود عن طريق تحديد المتطلبات الأدنى. يفشل البناء إذا لم تتم استيفاء هذه المتطلبات، وإلا يكون البناء ناجحًا.

6. يمكن تحديد هذه المتطلبات كقواعد في POM.xml. فقط حدد التنفيذ الجديد عن طريق تحديد هدف ‘check’ في POM.xml. أضف الكود التالي بعد علامة <execution> الثانية في POM.xml.

 

<!--Third execution : used to put a check on the entire package-->
<execution>
    <id>jacoco-check</id>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule>
                <element>PACKAGE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.50</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>

7. بهذا، نحن نحد من نسبة التغطية لدينا إلى 50%. وهذا يعني أن على الأقل 50% من الكود يجب أن يتم تغطيته خلال مرحلة الاختبار.

8. يمكنك تشغيل Maven clean verify للتحقق مما إذا كانت القواعد المعلقة في هدف jacoco:check ملتزمة أم لا.

9. السجل يظهر “ملتزمة أم لا.تم استيفاء جميع فحوصات التغطية” لأن نسبة التغطية البرمجية لدينا هي 94٪، وهي أكبر من الحد الأدنى الخاص بنا الذي هو 50٪.

اختبار تلقائي على شبكة LambdaTest Selenium Grid

استخدام مشروع Maven مع ملحق JaCoCo

اختبار Selenium على السحابة يساعدك على الحصول على تغطية أفضل للمتصفحات، وزيادة فترة الاختبار، وتسريع وقت الوصول إلى السوق. الاختبار الموازي في Selenium يساعدك على تحقيق المتطلبات المذكورة أعلاه.

شبكة LambdaTest Cloud Selenium Grid هي منصة اختبار Selenium قابلة للتوسع تعتمد على السحابة والتي تمكنك من تشغيل سير التشغيل التلقائي على أكثر من 2000 متصفح ونظام تشغيل مختلف.

الشروط الأساسية

لتشغيل سطر الاختبار باستخدام JUnit مع Selenium، نحتاج إلى إعداد بيئة. يجب أولاً إنشاء حساب على LambdaTest. تأكد من تسجيل اسم المستخدم ومفتاح الوصول المتاح في قسم ملف التعريف في LambdaTest.

سنستخدم هذا المشروع النموذجي لاختبار Java Selenium.

استيراد المشروع إلى IDE Eclipse

بعد تنزيل ملف zip للمشروع: junit-selenium-sample من GitHub، سنقوم باستيراده إلى IDE Eclipse وفقًا للخطوات المذكورة أدناه:

1. اذهب إلى IDE الخاص بك في Eclipse، انقر على قائمة “ملف” واختر “استيراد”. تظهر مربع convsersation جديد.

2. اكتب Maven في مربع النص أسفله وحدد “المشاريع Maven الحالية”، ثم انقر على “التالي”.

3. في مربع convsersation التالي، انقر على “تصفح” وتعقب المجلد الذي يحتوي على مشروعك. أيضًا، اختر خانة الاختيار التي توفر المسار إلى ملف POM.xml، وانقر على “انهاء”.

4. سيتم تحميل مشروعك بنجاح في IDE Eclipse.

إضافة المراجع في ملف POM.xml

1. افتح ملف POM.xml، الآن أضف مراجع JUnit وSelenium وميزانية JaCoCo. بعد إضافة المراجع إلى الكود من POM.xml يجب أن يبدو هكذا:

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lambdatest</groupId>
    <artifactId>lambdatest-junit-sample</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <surefire.version>2.19.1</surefire.version>
        <config.file>default</config.file>
    </properties>

    <dependencies>
        <!--JUnit dependency-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
            <scope>test</scope>
        </dependency>
        <!--Selenium dependency-->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>2.52.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.json-simple</groupId>
            <artifactId>json-simple</artifactId>
            <version>1.1.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--Apache Maven Plugins-->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
            </plugin>
            <!--JaCoCo Maven Plugin-->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>      
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                      <goals><goal>prepare-agent</goal></goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals><goal>report</goal></goals>
                   </execution>
               </executions>
          </plugin>
        </plugins>
    </build>
</project>

 
<em><a href="https://github.com/rachnaagrawal/junit-selenium-sample/blob/master/pom.xml" target="_blank" rel="nofollow">Github</a></em>

تكوين القدرات المرغوبة لاختبارات تحليل الجمل الضوئية

1. للاتصال بشبكة LambdaTest Selenium Automation Grid، الشيء الأول الذي يتم القيام به هو استدعاء ويب درايف عن بعد. يتطلب هذا السائق البعيد بعض القدرات مثل المتصفح وإصدارات المتصفح ونظام التشغيل ، الخ ، لبناء بيئة. يبدو الكود لذلك كما يلي:

 

WebDriver driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + "@hub.lambdatest.com/wd/hub"),
DesiredCapabilities.firefox()); //A class named DesiredCapabilities is used to create an environment as a Firefox browser.

2. في رمز اختبار تحليل الجمل الضوئية، يمكن تخصيص القدرات مثل المتصفح وإصدارات المتصفح ومعلومات نظام التشغيل ، الخ ، ويتم تمريرها عبر كائن القدرات.

3. LambdaTest جعلت هذه العملية سهلة للغاية من خلال توفير مولد قدرات مدمج. سيولد مولد القدرات المرغوبة تلقائيًا الرمز للقدرات المرغوبة استنادًا إلى مدخلاتك. مثل، تكويناتنا هي:

الحقول

قيم مختارة

أنظمة التشغيل

Windows 10

متصفح

Chrome

إصدار المتصفح

62.0

الدقة

1024×768

إصدار Selenium

3.13.0

4. تحديد الإعداد المحدد أعلاه في مولد القدرات ولصقه في LambdaTestBaseTest.java.

تحديد اسم مستخدم LambdaTest ومفتاح الوصول في الفئة المطلوبة الإصدار العربي

1. في Project Explorer، سترى ثلاث فئات جافا:

  • LambdaTestBaseTest.java (تحتوي على الإعداد المطلوب لإختبار Java Selenium).
  • Parallelized.java (تحتوي على اختبارات Junit للتجارب الموازية على شبكة LambdaTest Selenium).
  • SimpleTest.java (تحتوي على اختبارات الوحدة البسيطة).

2. LambdaTestBaseTest.java يستقبل البيانات المطلوبة مثل القدرات المرغوبة واسم المستخدم ومفتاح الوصول من ملف تكوين. وهذا مقدم في src/test/resources كـ config.json.

3. تحديد القدرات المرغوبة واسم المستخدم ومفتاح الوصول في config.json. يتم استخدام ملف JSON هذا لأنه يمكنك توفير إعدادات متعددة فيه لتحقيق الاختبار الموازي مع Selenium لتحديد إعدادات متعددة في config.json ثم استدعائها لاحقًا.

 

[ { "tunnelName":"LambdaTest tunnel", 
"buildName":"running Java Selenium Tests",
"testName":"Jacoco JUnit Test",
"username": "user-name",
"access_key":"access-key", 
 "operatingSystem" : "win10", 
 "browserName" : "chrome",  
 "browserVersion" : "62.0", 
 "resolution" : "1024x768" }]

اختبار الوحدة باستخدام JUnit مع Selenium:

1. SimpleTest.java هو الفصل الذي يحدد حالة اختبار وحدة واحدة في Java للاختبار وإجراء تغطية الكود باستخدام ملحق JaCoCo في Maven.

 

package com.lambdatest;

import com.lambdatest.LambdaTestBaseTest;
import org.junit.Test;
import org.openqa.selenium.By;
import static org.junit.Assert.assertEquals;

public class SimpleTest extends LambdaTestBaseTest {
    /**
     * Simple Test case annotation for JUnit Test
     * @throws Exception
     */

   @Test
    public void validateUser() throws Exception {
    	  driver.get("https://lambdatest.github.io/sample-todo-app/");
	  driver.findElement(By.name("li1")).click();
	  driver.findElement(By.name("li2")).click();
	  driver.findElement(By.id("sampletodotext")).clear();
	  driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
	  driver.findElement(By.id("addbutton")).click();
    }

}

2. هذا اختبار بسيط لـ Selenium WebDriver يفتح تطبيق عينة للقيام بالمهام التالية:

  • ضع علامة على أول عنصرين بـ “تم.
  • أضف عنصرًا جديدًا إلى القائمة.
  • إرجاع العنصر المضاف.

3. قم بتشغيل الأمر mvn test في المحطة لبناء وتشغيل حالة الاختبار.

4. الآن، تسجيل الدخول إلى حساب LambdaTest الخاص بك والانتقال إلى “الأتمتة“. ستجد الاختبارات التي أجريت تحت اسم البناء “JUnit JaCoCo Tests”.

5. انقر على “JUnit JaCoCo Tests” وراجعها بالتفصيل. لقد تم تسجيل الفيديو من قبل LambdaTest. لذا يمكنك أيضًا مشاهدة الصور.

توليد تقرير تغطية الكود عبر ملحق JaCoCo في Maven:

  1. الآن، بما أننا قمنا بتشغيل اختبارات JUnit على شبكة Selenium في LambdaTest، يجب توليد تقرير تغطية الكود عبر ملحق JaCoCo في Maven.
  2. فقط انتقل إلى مجلد الهدف، وستجد النموذج الثنائي للتقرير كـ jacoco.exec.
  3. يمكنك مشاهدة النموذج الإلكتروني، والإكسل، والنموذج الشبكي لتقرير تغطية الكود في مجلد target/site/jacoco كـ index.html, jacoco.csv، و jacoco.xml على التوالي.
  4. الآن يمكنك أيضًا محاولة تحسين نتيجة تغطية الكود وتحليل تقرير تغطية الكود المتولد.

الخاتمة

في هذا المقال، قد شرحنا كيفية استخدام ملفات JaCoCo-Maven لإنشاء تقارير حول تغطية الكود لمشاريع Java. كما تم استغلال التنوع والقابلية للتوسع في شبكة LambdaTest Selenium Grid السحابية لأتمتة عمليات الاختبار. تذكر أن تغطية الكود بنسبة 100% لا تعكس الاختبار الفعال، حيث تظهر فقط مقدار الكود الذي تم تنفيذه خلال الاختبارات.

ومع ذلك، هذا يساعد على تقليل عدد البقايا وتحسين جودة الإصدارات البرمجية. أيضاً، هذا يضيف إضافة طفيفة لعملية البناء ويسمح لها بالحفاظ على حد معين بينما يضيف فريق التطوير حالات لبناء البرمجة أو ينفذ برمجة وقائية.

Source:
https://dzone.com/articles/how-to-generate-code-coverage-report-jacoco-maven