精简地报告 Bug
这篇文章是继之前一篇关于在开源社区支持用户的文章,列出了一些关于如何向维护者寻求帮助的建议。
您不必遵循这些建议。它们是可选的。但遵循这些建议可以增加项目维护者花时间帮助您的可能性。重要的是要记住,他们免费支持您的意愿也是可选的。
精简地报告 Bug 对于社区驱动的开源项目的生存和维护至关重要。做好这一点是对社区的巨大贡献。
最小化、完整且可验证的示例
我强烈建议遵循 Stack Overflow 关于最小化、完整且可验证示例的指南。我在这里简要概述一下重点。
……代码应该是……
最小化 – 使用尽可能少的代码,但仍然能重现相同的问题。
完整 – 提供重现问题所需的所有部分。
可验证 – 测试您即将提供的代码,确保它可以重现问题。
需要明确的是,这很困难,并且需要花费时间。
作为提问者,我发现对于一个简单的问题,创建 MCVE 通常需要 10 到 30 分钟。幸运的是,这项工作通常很简单,即使我对遇到问题的软件包不太了解。创建最小示例的大部分工作是移除所有特定于我应用程序的代码,而作为提问者,我可能是最适合做这件事的人。
在回答问题时,我经常会把人们引向 StackOverflow 的 MCVE 文档。他们有时会带着一个更好但还不够最小化的示例回来。这篇文章澄清了一些常见问题。
作为一个运行示例,我将使用 Pandas DataFrame 的问题。
不要上传数据
您不应该上传您正在处理的文件。相反,尝试看看是否只需要几行数据就能重现问题,而不是整个文件。
必须下载文件、解压缩等等,这使得人们在业余时间实际运行您的示例的可能性大大降低。
错误示例
我已将数据上传到 Dropbox,您可以在这里获取:my-data.csv.gz
import pandas as pd
df = pd.read_csv('my-data.csv.gz')
正确示例
您应该能够复制粘贴以下内容来获取足够多的数据以重现问题
import pandas as pd
df = pd.DataFrame({'account-start': ['2017-02-03', '2017-03-03', '2017-01-01'],
'client': ['Alice Anders', 'Bob Baker', 'Charlie Chaplin'],
'balance': [-1432.32, 10.43, 30000.00],
'db-id': [1234, 2424, 251],
'proxy-id': [525, 1525, 2542],
'rank': [52, 525, 32],
...
})
实际上根本不要包含您的数据
实际上,您的数据可能包含许多特定于您应用程序的信息。您可能会忽略它,但维护者不知道哪些是相关的,哪些不是,所以如果您包含这些数据,他们需要时间来理解。相反,看看您是否可以使用人工生成或随机数据来重现相同的错误。
错误示例
以下数据足以重现问题
import pandas as pd
df = pd.DataFrame({'account-start': ['2017-02-03', '2017-03-03', '2017-01-01'],
'client': ['Alice Anders', 'Bob Baker', 'Charlie Chaplin'],
'balance': [-1432.32, 10.43, 30000.00],
'db-id': [1234, 2424, 251],
'proxy-id': [525, 1525, 2542],
'rank': [52, 525, 32],
...
})
正确示例
我实际的问题是关于在特定时间段内找到排名最高的员工,但我们可以使用这个更简单的数据集来重现问题。注意这些数据中的日期是乱序的(2000-01-02 在 2000-01-03 之后)。我发现这对于重现错误至关重要。
import pandas as pd
df = pd.DataFrame({'account-start': ['2000-01-01', '2000-01-03', '2000-01-02'],
'db-id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'})
当我们缩小示例问题时,我们常常会发现很多关于问题原因的信息。这个发现非常有价值,而且只有提问者才能高效地完成。
看看能把示例弄得多小
为了更容易,看看您能把数据弄得多小。例如,如果处理表格数据(如 Pandas),那么您实际需要多少列来重现错误?您实际需要多少行来重现错误?列名是否需要和您现在的一样,还是可以用“A”和“B”或者描述数据类型来代替?
正确示例
import pandas as pd
df = pd.DataFrame({'datetime': ['2000-01-03', '2000-01-02'],
'id': [1, 2]})
移除不必要的步骤
您示例中的每一行对于重现错误都是绝对必要的吗?如果您能够删除一行代码,请删除。因为您已经理解您的问题,所以在这方面您比维护者要高效得多。他们可能更了解这个工具,但您更了解您的代码。
错误示例
下面的 groupby 步骤触发了一个我不理解的警告
df = pd.DataFrame(...)
df = df[df.value > 0]
df = df.fillna(0)
df.groupby(df.x).y.mean() # <-- this produces the error
正确示例
下面的 groupby 步骤触发了一个我不理解的警告
df = pd.DataFrame(...)
df.groupby(df.x).y.mean() # <-- this produces the error
使用语法高亮
在使用 Github 时,您可以使用三个反引号(美式标准 QWERTY 键盘左上角的字符)将代码块括起来。就像这样
```python
x = 1
```
提供完整的堆栈跟踪信息 (tracebacks)
您知道代码和异常之间那些难以理解的所有内容吗?您应该把它们都包含进去。
错误示例
I get a ZeroDivisionError from the following code:
```python
def div(x, y):
return x / y
div(1, 0)
```
正确示例
I get a ZeroDivisionError from the following code:
```python
def div(x, y):
return x / y
div(1, 0)
```
```python-traceback
ZeroDivisionError Traceback (most recent call last)
<ipython-input-4-7b96263abbfa> in <module>()
----> 1 div(1, 0)
<ipython-input-3-7685f97b4ce5> in div(x, y)
1 def div(x, y):
----> 2 return x / y
3
ZeroDivisionError: division by zero
```
如果堆栈跟踪信息很长,没关系。如果您真的想整洁,可以将其放在 <details>
标签中。
I get a ZeroDivisionError from the following code:
```python
def div(x, y):
return x / y
div(1, 0)
```
### Traceback
<details>
```python
ZeroDivisionError Traceback (most recent call last)
<ipython-input-4-7b96263abbfa> in <module>()
----> 1 div(1, 0)
<ipython-input-3-7685f97b4ce5> in div(x, y)
1 def div(x, y):
----> 2 return x / y
3
ZeroDivisionError: division by zero
```
</details>
在公共场所提问
当报告问题时,您通常有几个可能的地点
- GitHub 问题跟踪器
- Stack Overflow
- 项目邮件列表
- 项目聊天室
- 直接给维护者发送电子邮件(千万不要这样做)
不同的项目对此的处理方式不同,但通常他们的文档中会有关于在哪里寻求帮助的页面。这通常标有“社区”、“支持”或“在哪里寻求帮助”。以下是来自 Pandas 社区的建议。
通常,最好在许多维护者都能看到您的提问并提供帮助的地方提问,这样其他用户将来遇到类似问题时也能找到您的提问和回答。
您的目标可能是解决您的问题,而维护者的目标可能在于记录如何解决您这类问题。这有助于将来遇到类似问题的更多用户,他们可以看到您精心编写的 bug 报告,并从讨论中学习。
我的个人偏好
- 对于像“如何正确地做 X?”这样的用户问题,我更倾向于 Stack Overflow。
- 对于像“我做了 X,我很确定它应该可以工作,但我遇到了这个错误”这样的 bug 报告,我更倾向于 Github issues。
- 对于一般性的闲聊,我更喜欢 Gitter,但实际上,我个人几乎不在 Gitter 上花时间,因为它不容易被未来的用户搜索到。如果您在 Gitter 上问我问题,我几乎肯定不会回复,除非是引导您到 github、stack overflow 或这篇博文。
- 我只喜欢在有人提议资助或以某种方式认真支持项目时收到个人电子邮件。
但再说一次,不同的项目有不同的做法和策略。您应该查看您正在使用的项目的文档,了解他们如何喜欢支持用户。
博客评论由 Disqus 提供支持