تمرين - إجراء اختبار تغطية التعليمات البرمجية

مكتمل

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

عندما تستهدف تطبيقات .NET لتعمل على Linux، فإن coverlet هو خيار شائع. Coverlet عبارة عن مكتبة متعددة الأنظمة الأساسية تغطي التعليمات البرمجية لـ .NET.

كيف تتم تغطية التعليمات البرمجية في .NET؟

تعتمد الطريقة التي تجمع بها تغطية التعليمات البرمجية على لغة البرمجة وأطر العمل التي تستخدمها، وأدوات تغطية التعليمات البرمجية المتاحة.

في سيناريو Tailspin، نجد ما يلي:

  • يوفر Visual Studio على Windows طريقة لإجراء تغطية التعليمات البرمجية.

  • ومع ذلك، نظرا لأننا نبني على Linux، يمكننا استخدام coverlet، وهي مكتبة تغطية التعليمات البرمجية عبر الأنظمة الأساسية ل .NET.

    يتطلب مشروع اختبار الوحدة حزمة nuGet coverlet.msbuild .

  • تتم كتابة نتائج تغطية التعليمات البرمجية إلى ملف XML بحيث يمكن معالجتها بواسطة أداة أخرى. تدعم Azure Pipelines تنسيقات نتائج تغطية Cobertura وJaCoCo.

    لهذه الوحدة النمطية، نحن نستخدم Cobertura.

  • لتحويل نتائج تغطية Cobertura إلى تنسيق يمكن للبشر قراءته، يمكننا استخدام أداة تسمى ReportGenerator.

  • يوفر ReportGenerator عددًا من التنسيقات، بما في ذلك HTML. تنشئ تنسيقات HTML تقارير مفصلة لكل فئة في مشروع .NET.

    على وجه التحديد، هناك تنسيق HTML يسمى HtmlInline_AzurePipelines، والذي يوفر مظهرا مرئيا يطابق Azure Pipelines.

كيف يمكنني إدارة أدوات .NET؟

أداة .NET مثل ReportGenerator هي حِزمة NuGet خاصة تحتوي على تطبيق وحدة تحكم. يمكنك إدارة أداة .NET كأداة عمومية أو كأداة محلية.

يتم تثبيت أداة عمومية في موقع مركزي ويمكن استدعاؤها من أي دليل. يتم استخدام إصدار واحد من أداة عمومية لجميع الدلائل على الجهاز.

الأداة المحلية هي نسخة أكثر عزلة من أداة .NET التي يتم تحديد نطاقها حسب دليل معين. يمكن النطاق الدلائل المختلفة من احتواء إصدارات مختلفة من نفس الأداة.

يمكنك استخدام ملف بيان لإدارة الأدوات المحلية لدليل معين. هذا الملف بتنسيق JSON ويسمى عادة dotnet-tools.json. يسمح لك ملف البيان بوصف إصدارات الأدوات المحددة التي تحتاجها لإنشاء تطبيقك أو تشغيله.

عند تضمين ملف البيان في التحكم بالمصادر ومصادر التطبيق، يمكن للمطورين وأنظمة الإنشاء تشغيل الأمر dotnet tool restore لتثبيت جميع الأدوات المدرجة في ملف البيان. عندما تحتاج إلى إصدار أحدث من أداة محلية، يمكنك ببساطة تحديث الإصدار في ملف البيان.

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

تشغيل تغطية التعليمات البرمجية محليا

قبل كتابة أي تعليمة برمجية للبنية الأساسية لبرنامج ربط العمليات التجارية، يمكنك تجربة الأشياء يدويا للتحقق من العملية.

  1. في Visual Studio Code، افتح المحطة الطرفية المتكاملة.

  2. قم بتشغيل الأمر التالي dotnet new لإنشاء ملف بيان أداة محلي.

    dotnet new tool-manifest
    

    ينشئ الأمر ملفا باسم .config/dotnet-tools.json.

  3. قم بتشغيل الأمر التالي dotnet tool install لتثبيت ReportGenerator:

    dotnet tool install dotnet-reportgenerator-globaltool
    

    يقوم هذا الأمر بتثبيت أحدث إصدار من ReportGenerator وإضافة إدخال إلى ملف بيان الأداة.

  4. تشغيل الأمر dotnet add package التالي لإضافة الحزمة coverlet.msbuild إلى مشروع Tailspin.SpaceGame.Web.Tests:

    dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
    
  5. قم بتشغيل الأمر التالي dotnet test لتشغيل اختبارات الوحدة الخاصة بك وجمع تغطية التعليمات البرمجية:

    إشعار

    إذا كنت تستخدم محطة PowerShell الطرفية في Visual Studio، فإن حرف متابعة السطر هو backtick (`)، لذا استخدم هذا الحرف بدلا من الحرف المائل المائل عكسيا (\) للأوامر متعددة الأسطر.

    dotnet test --no-build \
      --configuration Release \
      /p:CollectCoverage=true \
      /p:CoverletOutputFormat=cobertura \
      /p:CoverletOutput=./TestResults/Coverage/
    

    إذا فشل الأمر، فحاول تشغيله كما يلي:

    MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \
      --configuration Release \
      /p:CollectCoverage=true \
      /p:CoverletOutputFormat=cobertura \
      /p:CoverletOutput=./TestResults/Coverage/
    

    يشبه هذا الأمر الأمر الذي قمت بتشغيله مسبقا. /p: تخبر العلامات coverlet بتنسيق تغطية التعليمات البرمجية الذي يجب استخدامه ومكان وضع النتائج.

  6. قم بتشغيل الأمر التالي dotnet tool run لاستخدامه ReportGenerator لتحويل ملف Cobertura إلى HTML:

    dotnet tool run reportgenerator \
      -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \
      -targetdir:./CodeCoverage \
      -reporttypes:HtmlInline_AzurePipelines
    

    يظهر عدد من ملفات HTML في مجلد CodeCoverage في جذر المشروع.

  7. في Visual Studio Code، قم بتوسيع مجلد CodeCoverage، وانقر بزر الماوس الأيمن فوق index.htm، ثم حدد Reveal in مستكشف الملفات (Reveal in Finder on macOS أو Open Containing Folder on Linux).

  8. في مستكشف Windows (الباحث على macOS)، انقر نقرا مزدوجا فوق index.htm لفتحه في مستعرض ويب.

    سترى ملخص تقرير التغطية.

    A screenshot of the local code coverage report summary showing 7.7 percent line coverage.

  9. قم بالتمرير إلى أسفل الصفحة للاطلاع على تصنيف التغطية حسب نوع الفئة.

    A screenshot of local coverage report class summary showing coverage stats across classes found in the Tailspin.SpaceGame.Web code.

  10. حدد الارتباط لعرض TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T> مزيد من التفاصيل.

    لاحظ أن GetItemsAsync الأسلوب مشمول باختبارات الوحدة، ولكن CountItemsAsync الأسلوب ليس له تغطية.

    A screenshot of local class coverage detail with a visual representation of unit test coverage for two C# methods, one with all code lines green (covered) and one with all lines red (not covered).

    هذا منطقي، لأن FetchOnlyRequestedGameRegion أسلوب الاختبار يستدعي GetItemsAsync الأسلوب ، ولكنه لا يستدعي CountItemsAsync الأسلوب . (لمراجعة رمز الاختبار، انظر إلىملف DocumentDBRepository_GetItemsAsyncShould.cs .)

إنشاء فرع

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

في هذا القسم، ستقوم بإنشاء فرع باسم code-coverage، استنادا unit-tests إلى الفرع، للاحتفاظ بعملك. في الممارسة العملية، عادة ما تقوم بإنشاء هذا الفرع من main الفرع.

  1. في Visual Studio Code، افتح المحطة الطرفية المتكاملة.

  2. في المحطة الطرفية، قم بتشغيل الأمر التالي git checkout لإنشاء فرع باسم code-coverage:

    git checkout -B code-coverage
    

إضافة مهام الإنشاء

في هذا القسم، ستضيف المهام التي تقيس تغطية التعليمات البرمجية إلى البنية الأساسية لبرنامج ربط العمليات التجارية للبناء.

  1. قم بتعديل azure-pipelines.ymlفي تعليمة Visual Studio البرمجية، كما يلي:

    trigger:
    - '*'
    
    pool:
      vmImage: 'ubuntu-20.04'
      demands:
      - npm
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.x'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK $(dotnetSdkVersion)'
      inputs:
        version: '$(dotnetSdkVersion)'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    
    - task: gulp@1
      displayName: 'Run gulp tasks'
    
    - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
      displayName: 'Write build info'
      workingDirectory: $(wwwrootDir)
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Build the project - $(buildConfiguration)'
      inputs:
        command: 'build'
        arguments: '--no-restore --configuration $(buildConfiguration)'
        projects: '**/*.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Install .NET tools from local manifest'
      inputs:
        command: custom
        custom: tool
        arguments: 'restore'
    
    - task: DotNetCoreCLI@2
      displayName: 'Run unit tests - $(buildConfiguration)'
      inputs:
        command: 'test'
        arguments: '--no-build --configuration $(buildConfiguration) /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=$(Build.SourcesDirectory)/TestResults/Coverage/'
        publishTestResults: true
        projects: '**/*.Tests.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Create code coverage report'
      inputs:
        command: custom
        custom: tool
        arguments: 'run reportgenerator -reports:$(Build.SourcesDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines'
    
    - task: PublishCodeCoverageResults@1
      displayName: 'Publish code coverage report'
      inputs:
        codeCoverageTool: 'cobertura'
        summaryFileLocation: '$(Build.SourcesDirectory)/**/coverage.cobertura.xml'
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish the project - $(buildConfiguration)'
      inputs:
        command: 'publish'
        projects: '**/*.csproj'
        publishWebProjects: false
        arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
        zipAfterPublish: true
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    يعتمد هذا الإصدار على التكوين الحالي. فيما يلي ملخص لما هو جديد:

    مهمة Azure Pipelines اسم العرض ‏‏الوصف
    DotNetCoreCLI@2 تثبيت أدوات .NET من البيان المحلي تثبيت الأدوات المدرجة في ملف البيان، dotnet-tools.json
    DotNetCoreCLI@2 تشغيل اختبارات الوحدة - $(buildConfiguration) يقوم بتشغيل اختبارات الوحدة ويجمع أيضا تغطية التعليمات البرمجية بتنسيق Cobertura
    DotNetCoreCLI@2 إنشاء تقرير تغطية التعليمات البرمجية تحويل إخراج Cobertura إلى HTML
    PublishCodeCoverageResults@1 نشر تقرير تغطية التعليمات البرمجية نشر التقرير إلى البنية الأساسية لبرنامج ربط العمليات التجارية

تنفيذ التغييرات ودفع الفرع إلى GitHub

هنا يمكنك دفع التغييرات الخاصة بك إلى GitHub ورؤية تشغيل البنية الأساسية لبرنامج ربط العمليات التجارية. تذكر أنك حاليا في code-coverage الفرع.

على الرغم من أنه غير مطلوب، فستقوم هنا بإضافة كل ملف وتثبيته بشكل منفصل بحيث يقترن كل تغيير برسالة تثبيت وصفية.

  1. في Visual Studio Code، انتقل إلى الموصل الطرفي.

  2. إضافة الملف Tailspin.SpaceGame.Web.Tests.csproj وتثبيته، الذي يحتوي الآن على مرجع إلى الحزمة coverlet.msbuild:

    git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj
    git commit -m "Add coverlet.msbuild package"
    
  3. إضافة ملف بيان الأداة وتثبيته، dotnet-tools.json:

    git add .config/dotnet-tools.json
    git commit -m "Add code coverage"
    
  4. إضافة وتثبيت azure-pipelines.yml، الذي يحتوي على تكوين البناء المحدث:

    git add azure-pipelines.yml
    git commit -m "Add code coverage"
    
  5. code-coverage ادفع الفرع إلى GitHub.

    git push origin code-coverage
    

شاهد Azure Pipelines تقوم بتشغيل الاختبارات

هنا، سترى الاختبارات قيد التشغيل في البنية الأساسية لبرنامج ربط العمليات التجارية ثم تصور النتائج من Azure Test Plans.

  1. في Azure Pipelines، تتبع البنية من خلال كل خطوة من الخطوات.

  2. عند انتهاء البنية، ارجع إلى صفحة Summary وحدد علامة التبويب Code Coverage .

    يمكنك عرض نفس النتائج التي قمت بها عند إجراء الاختبارات محليا.

    A screenshot of Azure Pipelines showing the Code Coverage tab, with code coverage report summary showing 7.7 percent line coverage.

    كخطوة اختيارية، يمكنك استكشاف النتائج من Azure Pipelines.

إضافة عنصر واجهة مستخدم لوحة المعلومات

في القسم السابق، أضفت عنصر واجهة مستخدم اتجاه نتائج الاختبار إلى لوحة المعلومات، مما يتيح للآخرين مراجعة اتجاهات نتائج الاختبار بسرعة بمرور الوقت.

هنا، ستضيف عنصر واجهة مستخدم ثان يلخص تغطية التعليمات البرمجية.

  1. في علامة تبويب مستعرض جديدة، انتقل إلى marketplace.visualstudio.com.

  2. في علامة التبويب Azure DevOps، ابحث عن تغطية التعليمات البرمجية.

  3. حدد Code Coverage Widgets (نشرت بواسطة Shane Davis).

  4. حدد الحصول عليه مجانا.

  5. في القائمة المنسدلة، حدد مؤسسة Azure DevOps.

  6. حدد تثبيت.

  7. ارجع إلى Azure DevOps.

  8. انتقل إلى Overview>Dashboards.

  9. حدد تحرير.

  10. ابحث عن تغطية التعليمات البرمجية، ثم حدد تغطية التعليمات البرمجية.

    A screenshot of Visual Studio Marketplace showing the Code Coverage widget card.

  11. اسحب Code Coverage إلى اللوحة.

  12. حدد أيقونة Gear لتكوين عنصر واجهة المستخدم.

  13. احتفظ بجميع الإعدادات الافتراضية، باستثناء:

    • العرض: أدخل 2
    • تعريف البناء: حدد البنية الأساسية لبرنامج ربط العمليات التجارية الخاصة بك
    • قياس التغطية: حدد خطوط
  14. حدد حفظ.

  15. حدد تم التحرير.

    يظهر عنصر واجهة المستخدم النسبة المئوية للتعليمات البرمجية التي تغطيها اختبارات الوحدة.

    A screenshot of Azure DevOps Code Coverage widget showing 8 percent coverage of the sample project.

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

لاحقا، يمكنك تكوين coverlet للتحقق لمعرفة ما إذا كانت اختباراتك توفر حدا أدنى من التغطية. قد تكون عتبتك تغطية بنسبة 30 بالمائة أو 50 بالمائة أو 80 بالمائة، اعتمادا على متطلباتك. ستفشل البنية إذا كانت اختباراتك تغطي أقل من هذا المبلغ.

إزالة ملفات تغطية التعليمات البرمجية

تذكر أنه عند تشغيل Reportgenerator في وقت سابق، ظهر عدد من ملفات HTML في مجلد CodeCoverage في جذر المشروع.

لم تُضمَن ملفات HTML هذه في عنصر التحكم بالمصادر، ولم تعد بحاجة إليها. على الرغم من أن ملف .gitignore الخاص بالمشروع قد تم إعداده بالفعل لتجاهل أي شيء في دليل CodeCoverage، فمن المستحسن حذف هذه الملفات بحيث لا تتم إضافتها إلى مستودع Git الخاص بك في الوحدات النمطية المستقبلية.

في تعليمة Visual Studio البرمجية، انتقل إلى نافذة terminal، ثم، في الدليل الجذر للمشروع، قم بتشغيل هذا الأمر:

rm -rf CodeCoverage/