Skip to content

Commit

Permalink
Merge pull request #50 from amosproj/34-Develop-and-Document-Basic-Te…
Browse files Browse the repository at this point in the history
…sting-Framework-for-Plugins-with-Example

34 develop and document basic testing framework for plugins with example
  • Loading branch information
QW3RAT authored Nov 21, 2023
2 parents d80395c + 8e37a41 commit 88faa16
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 159 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Build and Test

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Set up JDK
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'

- name: Build with Gradle
run: ./gradlew build --no-daemon

- name: Run Tests
run: ./gradlew test --no-daemon
Original file line number Diff line number Diff line change
Expand Up @@ -10,59 +10,96 @@ import javax.xml.parsers.DocumentBuilderFactory

class XMLParser {
fun loadResultsFromXmlReport(xmlReportPath: String?): ResultData {
// Implement the logic to parse the XML report and load key results into a data structure
val resultData = ResultData()
val documentBuilderFactory = DocumentBuilderFactory.newInstance()
val documentBuilder = documentBuilderFactory.newDocumentBuilder()
val document = documentBuilder.parse(File(xmlReportPath))
try {
val documentBuilderFactory = DocumentBuilderFactory.newInstance()
val documentBuilder = documentBuilderFactory.newDocumentBuilder()
val document = documentBuilder.parse(File(xmlReportPath))

val mutationsNodeList = document.getElementsByTagName("mutation")
val mutationsNodeList = document.getElementsByTagName("mutation")

for (i in 0 until mutationsNodeList.length) {
val mutationNode = mutationsNodeList.item(i)
for (i in 0 until mutationsNodeList.length) {
val mutationNode = mutationsNodeList.item(i)

if (mutationNode.nodeType == Node.ELEMENT_NODE) {
val element = mutationNode as Element
if (mutationNode.nodeType == Node.ELEMENT_NODE) {
val element = mutationNode as Element

val detected = element.getAttribute("detected").toBoolean()
val status = element.getAttribute("status")
val numberOfTestsRun = element.getAttribute("numberOfTestsRun").toInt()
val sourceFile = element.getElementsByTagName("sourceFile").item(0).textContent
val mutatedClass = element.getElementsByTagName("mutatedClass").item(0).textContent
val mutatedMethod = element.getElementsByTagName("mutatedMethod").item(0).textContent
val methodDescription = element.getElementsByTagName("methodDescription").item(0).textContent
val lineNumber = element.getElementsByTagName("lineNumber").item(0).textContent.toInt()
val mutator = element.getElementsByTagName("mutator").item(0).textContent
val indexesNodeList = element.getElementsByTagName("index")
val indexes = (0 until indexesNodeList.length).map { indexesNodeList.item(it).textContent.toInt() }
val blocksNodeList = element.getElementsByTagName("block")
val blocks = (0 until blocksNodeList.length).map { blocksNodeList.item(it).textContent.toInt() }
val killingTest = element.getElementsByTagName("killingTest").item(0).textContent
val description = element.getElementsByTagName("description").item(0).textContent
val detected = getAttribute(element, "detected", false)
val status = getAttribute(element, "status", "N/A")
val numberOfTestsRun = getAttribute(element, "numberOfTestsRun", -1)
val sourceFile = getTextContent(element, "sourceFile")
val mutatedClass = getTextContent(element, "mutatedClass")
val mutatedMethod = getTextContent(element, "mutatedMethod")
val methodDescription = getTextContent(element, "methodDescription")
val lineNumber = getAttribute(element, "lineNumber", -1)
val mutator = getTextContent(element, "mutator")
val indexes = getListContent(element, "index")
val blocks = getListContent(element, "block")
val killingTest = getTextContent(element, "killingTest")
val description = getTextContent(element, "description")

// Create a MutationResult object and add it to the data structure
val mutationResult = MutationResult(
detected,
status,
numberOfTestsRun,
sourceFile,
mutatedClass,
mutatedMethod,
methodDescription,
lineNumber,
mutator,
indexes,
blocks,
killingTest,
description
)
resultData.addMutationResult(mutationResult)
val mutationResult = MutationResult(
detected,
status,
numberOfTestsRun,
sourceFile,
mutatedClass,
mutatedMethod,
methodDescription,
lineNumber,
mutator,
indexes,
blocks,
killingTest,
description
)
resultData.addMutationResult(mutationResult)
}
}
} catch (e: Exception) {
//TODO: Handle Parser exceptions
e.printStackTrace()
}

return resultData
}

private fun getTextContent(element: Element, tagName: String): String {
val nodeList = element.getElementsByTagName(tagName)
return if (nodeList.length > 0) {
nodeList.item(0).textContent
} else {
"N/A"
}
}

private fun getListContent(element: Element, tagName: String): List<Int> {
val nodeList = element.getElementsByTagName(tagName)
return if (nodeList.length > 0) {
(0 until nodeList.length).map { nodeList.item(it).textContent.toInt() }
} else {
emptyList()
}
}

private fun <T> getAttribute(element: Element, attributeName: String, defaultValue: T): T {
return try {
val attributeValue = element.getAttribute(attributeName)
if (attributeValue.isNotEmpty()) {
when (defaultValue) {
is Boolean -> attributeValue.toBoolean() as T
is Int -> attributeValue.toInt() as T
is String -> attributeValue as T
else -> defaultValue
}
} else {
defaultValue
}
} catch (e: Exception) {
defaultValue
}
}

data class ResultData(
val mutationResults: MutableList<MutationResult> = mutableListOf()
) {
Expand All @@ -87,3 +124,4 @@ class XMLParser {
val description: String
)
}

107 changes: 0 additions & 107 deletions pitmutationmate/src/main/resources/test_report/index.html

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2023

package com.amos.pitmutationmate.pitmutationmate

import org.junit.Test
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import java.io.File

class XMLParserTests{
fun getTestInputFilepath(filename: String): File {
val classLoader = Thread.currentThread().contextClassLoader
val resource = classLoader.getResource(filename)
val file = File(resource.file)
return file

private fun getTestInputFilepath(filename: String): File {
val path = "src/test/resources/$filename"

return File(path)
}

@Test
fun testloadResultsFromXmlReportFlyerReport(){
fun loadResultsFromXml_reportFlyerReport() {
val file = getTestInputFilepath("test_report/mutations.xml")
val parser = XMLParser()
val actualResultData = parser.loadResultsFromXmlReport(file.absolutePath)
Expand All @@ -35,6 +32,21 @@ class XMLParserTests{
assertEquals("lambda\$calculateValue\$1", seventhMutationResult.mutatedMethod)
}

@Test
fun loadResultFromXml_missingXmlNode(){
val file = getTestInputFilepath("test_report/mutations_missingXmlNode.xml")
val parser = XMLParser()
val actualResultData = parser.loadResultsFromXmlReport(file.absolutePath)

assertTrue(actualResultData.mutationResults.isNotEmpty())
}

@Test
fun loadResultFromXml_additionalXmlNode(){
val file = getTestInputFilepath("test_report/mutations_additionalNodes.xml")
val parser = XMLParser()
val actualResultData = parser.loadResultsFromXmlReport(file.absolutePath)

}
assertTrue(actualResultData.mutationResults.isNotEmpty())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<mutations>
<mutation detected='true' status='KILLED' numberOfTestsRun='1'>
<sourceFile>Presenter.java</sourceFile>
<mutatedClass>de.esolutions.pitest.showcase.Presenter</mutatedClass>
<mutatedMethod>&lt;init&gt;</mutatedMethod>
<additionalTestNode>test</additionalTestNode>
<methodDescription>(Lde/esolutions/pitest/showcase/View;Lde/esolutions/pitest/showcase/Model;)V</methodDescription>
<lineNumber>10</lineNumber>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator</mutator>
<indexes><index>15</index></indexes>
<blocks><block>1</block></blocks>
<killingTest>de.esolutions.pitest.showcase.PresenterTest.[engine:junit-jupiter]/[class:de.esolutions.pitest.showcase.PresenterTest]/[method:shouldSetDataCorrectlyWhenFilterIsSet()]</killingTest>
<description>removed call to de/esolutions/pitest/showcase/View::onFilterSelected</description></mutation>
</mutations>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<mutations>
<mutation detected='true' status='KILLED' >
<sourceFile>Presenter.java</sourceFile>
<mutatedClass>de.esolutions.pitest.showcase.Presenter</mutatedClass>
<methodDescription>(Lde/esolutions/pitest/showcase/View;Lde/esolutions/pitest/showcase/Model;)V</methodDescription>
<lineNumber>10</lineNumber>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator</mutator>
<indexes><index>15</index></indexes>
<blocks><block>1</block></blocks>
<killingTest>de.esolutions.pitest.showcase.PresenterTest.[engine:junit-jupiter]/[class:de.esolutions.pitest.showcase.PresenterTest]/[method:shouldSetDataCorrectlyWhenFilterIsSet()]</killingTest>
<description>removed call to de/esolutions/pitest/showcase/View::onFilterSelected</description>
</mutation>
</mutations>

0 comments on commit 88faa16

Please sign in to comment.