有什么区别? (Python 单元测试失败(?)由于多行字符串中的前导空格)

What the Diff? (Python unittest failing (?) due to leading whitespace in multine strings)

我正在尝试在 HTML 中建立一个月的 header 行。我有一个测试用例,当我目视检查比较或我的代码生成的部分时,我得到一个断言错误(例如,我的案例没有通过)。奇怪的是,当我目视检查时,SEEM 的输出是相同的。

我做了一些摆弄,缩小了问题的范围。请看下面的代码。

这是我的测试用例:

class xyz(unittest.TestCase):

    def test__render_table_header(self):
        self.maxDiff = None
        testy = self.testcal1
        htmltest = testy._render_table_header(date(2014, 8, 1))
        htmlcase = """<table>
            <th colspan='7'>
                <div class="headercontainer">
                    <div class="montheader">{}</div>
                    <div class="yearheader">{}</div>
                </div>
            </th>
            <tr>
                <td class='dayheader'>Sun</td>
                <td class='dayheader'>Mon</td>
                <td class='dayheader'>Tues</td>
                <td class='dayheader'>Wed</td>
                <td class='dayheader'>Thurs</td>
                <td class='dayheader'>Fri</td>
                <td class='dayheader'>Sat</td>
            </tr>
            <tr>""".format('August', '2014')
        self.assertEqual(htmlcase, htmltest)

这是我的函数:

def _render_table_header(self, dateobj):

    TOP_OF_TABLE = """<table>
        <th colspan='7'>
            <div class="headercontainer">
                <div class="montheader">{}</div>
                <div class="yearheader">{}</div>
            </div>
        </th>
        <tr>
            <td class='dayheader'>Sun</td>
            <td class='dayheader'>Mon</td>
            <td class='dayheader'>Tues</td>
            <td class='dayheader'>Wed</td>
            <td class='dayheader'>Thurs</td>
            <td class='dayheader'>Fri</td>
            <td class='dayheader'>Sat</td>
        </tr>
        <tr>"""
    month = dateobj.strftime('%B')
    year = dateobj.strftime('%Y')
    return TOP_OF_TABLE.format(month, year)

这是我得到的错误和差异:

FAIL: test__render_table_header 

(__main__.test_enhanced_cal_helper_functions)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "court_app_timeline.py", line 430, in test__render_table_header
    self.assertEqual(htmlcase, htmltest)
AssertionError: '<table>\n            <th colspan=\'7\'>\n                <div [585 chars]<tr>' != '<table>\n                <th colspan=\'7\'>\n                 [649 chars]<tr>'
  <table>
-             <th colspan='7'>
+                 <th colspan='7'>
? ++++
-                 <div class="headercontainer">
+                     <div class="headercontainer">
? ++++
-                     <div class="montheader">August</div>
+                         <div class="montheader">August</div>
? ++++
-                     <div class="yearheader">2014</div>
+                         <div class="yearheader">2014</div>
? ++++
-                 </div>
+                     </div>
? ++++
-             </th>
+                 </th>
? ++++
-             <tr>
+                 <tr>
? ++++
-                 <td class='dayheader'>Sun</td>
+                     <td class='dayheader'>Sun</td>
? ++++
-                 <td class='dayheader'>Mon</td>
+                     <td class='dayheader'>Mon</td>
? ++++
-                 <td class='dayheader'>Tues</td>
+                     <td class='dayheader'>Tues</td>
? ++++
-                 <td class='dayheader'>Wed</td>
+                     <td class='dayheader'>Wed</td>
? ++++
-                 <td class='dayheader'>Thurs</td>
+                     <td class='dayheader'>Thurs</td>
? ++++
-                 <td class='dayheader'>Fri</td>
+                     <td class='dayheader'>Fri</td>
? ++++
-                 <td class='dayheader'>Sat</td>
+                     <td class='dayheader'>Sat</td>
? ++++
-             </tr>
+                 </tr>
? ++++
-             <tr>+                 <tr>? ++++


----------------------------------------------------------------------

我会向你们好人承认我不是最有才华的程序员。事实上,我的整个编程生涯只能追溯到大约 5 个月前。随之而来的是阅读差异时的某种无能。在我看来,输出之间的主要区别与前导空格有关。我该如何解决这个问题?

PS - 非常感谢任何提示、评论、指点等。

一个可能的解决方案是简单地匹配构成测试用例的字符串和函数中使用的字符串的缩进。这具有允许测试通过的效果。

然而,这似乎有点愚蠢(不可扩展,而且确实没有触及功能的核心)。简单地忽略前导空格会好得多。也许另一位评论者可以提供帮助。当我们这样做的时候,我很想听听人们的评论:在 python 中生成 HTML 以及确保正确嵌套标签的最佳方法是什么(为了视觉吸引力,如果没有别的)输出。

不要在两个不同的地方定义 HTML 代码。在一个处定义,在需要的地方使用。

一种常见的方法是将其定义为模块中的全局变量,然后从该模块中导入它。例如,您可以将其放在名为 html_examples.py:

的模块中
TABLE_CODE = """
    <table>
        <th colspan='7'>
         blah blah...
"""

然后当您需要在另一个模块中访问该文本时,您可以这样说:

from html_examples import TABLE_CODE

首先:多行字符串不考虑缩进。这意味着如果您的测试用例在 class 中并且您的生成器在函数中,那将是一个问题。

更有用的是,一般来说,空格在 HTML 中基本上是可以忽略的...我建议至少做一些类似的事情:

def strip_white_space(str):
   return str.replace(" ", "").replace("\t", "").replace("\n", "")

self.assertEqual(strip_white_space(htmlcase), strip_white_space(htmltest))

一个更好的方法是将两个字符串规范化,但我不知道该怎么做。 Clean Up HTML in Python 有一些建议,例如:

from BeautifulSoup import BeautifulSoup
htmlcase = BeautifulSoup(htmlcase).prettify()
htmltest = BeautifulSoup(htmltest).prettify()

(虽然我不确定是否会始终如一地删除空格)