Jeder der mit Selenium arbeitet, kann sicherlich einerseits eine Pipeline in Jenkins für das Reporting benutzten. Für lokale Testverfahren kann man sich aber auch recht schnell einen Report bauen.

 

Aktuell nutze ich in diversen Projekten hier den HTML TestRunner.

 

Wie man den html testrunner in sein Projekt implementiert könnt ihr hier sehen:

import HtmlTestRunner
import unittest


class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_error(self):
        """ This test should be marked as error one. """
        raise ValueError

    def test_fail(self):
        """ This test should fail. """
        self.assertEqual(1, 2)

    @unittest.skip("This is a skipped test.")
    def test_skip(self):
        """ This test should be skipped. """
        pass

if __name__ == '__main__':
    unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='example_dir'))

 

Im einzelnen also:

import HtmlTestRunner

Und am Ende des Source:

if __name__ == '__main__':
 unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='example_dir'))

Bitte beachten das ihr eventuell bei Windows die Slahes anpassen müsst für die Directory!

Wenn euch die Übersicht des Standard Templates nicht reichen solltet könnt ihr euch jederzeit ein eigenes Template bauen.

Anbei ein Beispiel Template: (Hier weiter beschrieben)

<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-xs-12">
                <h2 class="text-capitalize">{{ title }}</h2>
                <p class='attribute'><strong>Start Time: </strong>{{ header_info.start_time.strftime("%Y-%m-%d %H:%M:%S") }}</p>
                <p class='attribute'><strong>Duration: </strong>{{ header_info.duration }}</p>
                <p class='attribute'><strong>Summary: </strong>{{ header_info.status }}</p>
            </div>
        </div>
        {% for test_case_name, tests_results in all_results.items() %}
        {% if tests_results %}
        <div class="row">
            <div class="col-xs-12 col-sm-10 col-md-10">
                <table class='table table-hover table-responsive'>
                    <thead>
                        <tr>
                            <th>{{ test_case_name }}</th>
                            <th>Status</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for test_case in tests_results %}
                        <tr class='{{ status_tags[test_case.outcome] }}'>
                            <td class="col-xs-9">{{ test_case.test_description }}</td>
                            <td class="col-xs-3">
                                <span class="label label-{{ status_tags[test_case.outcome] }}">
                                    {% if test_case.outcome == test_case.SUCCESS %}
                                        Pass
                                    {% elif test_case.outcome == test_case.SKIP %}
                                        Skip
                                    {% elif test_case.outcome == test_case.FAILURE %}
                                        Fail
                                    {% else %}
                                        Error
                                    {% endif %}
                                </span>
                                {% if test_case.stdout or test_case.err %}
                                    &nbsp<button class="btn btn-default btn-xs">View</button>
                                {% endif %}
                            </td>
                        </tr>
                        {% if test_case.stdout or test_case.err or test_case.err %}
                            <tr style="display:none;">
                                <td class="col-xs-9">
                                    {% if test_case.stdout %}<p>{{ test_case.stdout }}</p>{% endif %}
                                    {% if test_case.err %}<p style="color:maroon;">{{ test_case.err[0].__name__ }}: {{ test_case.err[1] }}</p>{% endif %}
                                    {% if test_case.err %}<p style="color:maroon;">{{ test_case.test_exception_info }}</p>{% endif %}
                                </td>
                            </tr>
                        {% endif %}
                        {% endfor %}
                        <tr>
                            <td>
                               {{ summaries[test_case_name] }}
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        {% endif %}
        {% endfor %}
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            $('td').on('click', '.btn', function(e){
                e.preventDefault();
                var $this = $(this);
                var $nextRow = $this.closest('tr').next('tr');
                $nextRow.slideToggle("fast");
                $this.text(function(i, text){
                    if (text === 'View') {
                        return 'Hide';
                    } else {
                        return 'View';
                    };
                });
            });
        });
    </script>
</body>
</html>

Wie ihr euch ein Template erstellt findet ihr in weiteren Quellen (Hier zu finden).