20
novembre
2009
[Test][C#] Comment extraire la couverture de code programmatiquement (2/2) ?
novembre
2009
Un article de nico-pyright(c)
Pas de commentaires
Suite de mon précédent billet :
Le xml obtenu a la tête suivante :
<?xml version="1.0" standalone="yes"?>
<CoverageDSPriv>
<Module>
<ModuleName>DllTest2.dll</ModuleName>
[...]
<NamespaceTable>
<BlocksCovered>1</BlocksCovered>
<BlocksNotCovered>0</BlocksNotCovered>
<LinesCovered>2</LinesCovered>
<LinesNotCovered>0</LinesNotCovered>
<LinesPartiallyCovered>0</LinesPartiallyCovered>
<ModuleName>DllTest2.dll</ModuleName>
<NamespaceKeyName>DllTest2.dllDllTest2</NamespaceKeyName>
<NamespaceName>DllTest2</NamespaceName>
<Class>
<ClassKeyName>DllTest2.dllDllTest2Class2</ClassKeyName>
<ClassName>Class2</ClassName>
[...]
<NamespaceKeyName>DllTest2.dllDllTest2</NamespaceKeyName>
<Method>
<MethodKeyName>DllTest2.dll!2091</MethodKeyName>
<MethodName>Test()</MethodName>
<MethodFullName>Test()</MethodFullName>
<LinesCovered>2</LinesCovered>
<LinesPartiallyCovered>0</LinesPartiallyCovered>
<LinesNotCovered>0</LinesNotCovered>
<BlocksCovered>1</BlocksCovered>
<BlocksNotCovered>0</BlocksNotCovered>
[...]
</Method>
</Class>
</NamespaceTable>
</Module>
<Module>
<ModuleName>DllTest.dll</ModuleName>
<ImageSize>49152</ImageSize>
<ImageLinkTime>0</ImageLinkTime>
[...]
</Module>
<SourceFileNames>
<SourceFileID>1</SourceFileID>
<SourceFileName>C:\test\ExtractCoverage\DllTest2\Class1.cs</SourceFileName>
</SourceFileNames>
<SourceFileNames>
<SourceFileID>2</SourceFileID>
<SourceFileName>C:\test\ExtractCoverage\DllTest\Class1.cs</SourceFileName>
</SourceFileNames>
</CoverageDSPriv>
<CoverageDSPriv>
<Module>
<ModuleName>DllTest2.dll</ModuleName>
[...]
<NamespaceTable>
<BlocksCovered>1</BlocksCovered>
<BlocksNotCovered>0</BlocksNotCovered>
<LinesCovered>2</LinesCovered>
<LinesNotCovered>0</LinesNotCovered>
<LinesPartiallyCovered>0</LinesPartiallyCovered>
<ModuleName>DllTest2.dll</ModuleName>
<NamespaceKeyName>DllTest2.dllDllTest2</NamespaceKeyName>
<NamespaceName>DllTest2</NamespaceName>
<Class>
<ClassKeyName>DllTest2.dllDllTest2Class2</ClassKeyName>
<ClassName>Class2</ClassName>
[...]
<NamespaceKeyName>DllTest2.dllDllTest2</NamespaceKeyName>
<Method>
<MethodKeyName>DllTest2.dll!2091</MethodKeyName>
<MethodName>Test()</MethodName>
<MethodFullName>Test()</MethodFullName>
<LinesCovered>2</LinesCovered>
<LinesPartiallyCovered>0</LinesPartiallyCovered>
<LinesNotCovered>0</LinesNotCovered>
<BlocksCovered>1</BlocksCovered>
<BlocksNotCovered>0</BlocksNotCovered>
[...]
</Method>
</Class>
</NamespaceTable>
</Module>
<Module>
<ModuleName>DllTest.dll</ModuleName>
<ImageSize>49152</ImageSize>
<ImageLinkTime>0</ImageLinkTime>
[...]
</Module>
<SourceFileNames>
<SourceFileID>1</SourceFileID>
<SourceFileName>C:\test\ExtractCoverage\DllTest2\Class1.cs</SourceFileName>
</SourceFileNames>
<SourceFileNames>
<SourceFileID>2</SourceFileID>
<SourceFileName>C:\test\ExtractCoverage\DllTest\Class1.cs</SourceFileName>
</SourceFileNames>
</CoverageDSPriv>
Une fois ce fichier xml obtenu, on pourra lui appliquer une transformation xsl. Pour ce faire, j’ai écrit ce xsl tout simple qui gagnerait grandement a être amélioré :
1: <?xml version="1.0" encoding="iso-8859-1" ?>
2: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
3: <xsl:output method="html"/>
4: <xsl:decimal-format name="financial" decimal-separator="," grouping-separator=" " />
5: <xsl:template match="/CoverageDSPriv">
6: <html>
7: <head>
8: <title></title>
9: </head>
10: <body>
11: <xsl:for-each select="Module">
12: <table border="1">
13: <tr>
14: <td>
15: <xsl:value-of select="ModuleName" />
16: </td>
17: <td></td>
18: <td>Not Covered</td>
19: <td>Covered</td>
20: </tr>
21: <xsl:for-each select="NamespaceTable/Class">
22: <tr>
23: <td>
24: <xsl:value-of select="ClassName" />
25: </td>
26: <td></td>
27: <td></td>
28: <td></td>
29: </tr>
30: <xsl:for-each select="Method">
31: <tr>
32: <td></td>
33: <td>
34: <xsl:value-of select="MethodFullName" />
35: </td>
36: <td>
37: <xsl:value-of select="format-number(BlocksNotCovered * 100 div (BlocksCovered + BlocksNotCovered),'# ##0,00','financial')" />%
38: </td>
39: <td>
40: <xsl:value-of select="format-number(BlocksCovered * 100 div (BlocksCovered + BlocksNotCovered),'# ##0,00','financial')" />%
41: </td>
42: </tr>
43: </xsl:for-each>
44: </xsl:for-each>
45: </table>
46: <br/>
47: </xsl:for-each>
48: </body>
49: </html>
50: </xsl:template>
51: </xsl:stylesheet>
J’ai placé le fichier xsl en ressource, ce qui fait qu’on pourra effectuer la transformation ainsi :
1: public static string TransformCoverage(string file)
2: {
3: StreamReader sr = new StreamReader(file);
4: XmlReader xmlReader = XmlReader.Create(sr);
5:
6: Assembly assembly = Assembly.GetExecutingAssembly();
7: Stream reader = assembly.GetManifestResourceStream("MyNamespace.output.xsl");
8:
9: if (reader != null)
10: {
11: // on transforme le xsl
12: XmlReader xslReader = XmlReader.Create(reader);
13: XslCompiledTransform xslt = new XslCompiledTransform();
14: xslt.Load(xslReader);
15:
16: StringBuilder sb = new StringBuilder();
17: TextWriter tw = new StringWriter(sb);
18: xslt.Transform(xmlReader, new XsltArgumentList(), tw);
19:
20: string value = sb.ToString();
21:
22: tw.Close();
23: xslReader.Close();
24: reader.Close();
25: return value;
26: }
27: xmlReader.Close();
28: sr.Close();
29: throw new Exception("Impossible de récupérer le fichier xsl");
30: }
Il ne restera plus qu’à envoyer le mail, avec quelque chose du genre :
1: MailAddress from = new MailAddress("from@email.com");
2: MailMessage mailMessage = new MailMessage { From = from };
3: mailMessage.To.Add(new MailAddress("to@email.com"););
4:
5: mailMessage.Subject = "Rapport de couverture de code";
6: mailMessage.IsBodyHtml = true;
7: mailMessage.Body = body; // résultat de TransformCoverage
8:
9: SmtpClient smtpClient = new SmtpClient(smtpAddress);
10: smtpClient.Send(mailMessage);
Et voilà pour l’extraction de la couverture de code avec du code C#
On obtient le résultat suivant :
Commentaires récents
- [Tests] Arrange Act Assert, une traduction ? dans
- [UnitTest][C#] Tester une méthode privée dans
- Récupérer une valeur d’un contrôle depuis une autre Form / inclusions croisées et déclaration anticipée dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
Archives
- janvier 2013
- avril 2012
- janvier 2012
- juin 2011
- janvier 2011
- décembre 2010
- novembre 2010
- septembre 2010
- juin 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- août 2009
- juillet 2009
- mai 2009
- avril 2009
- mars 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008
- juillet 2008
- juin 2008
- mai 2008
- avril 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007