5

我一直在我一直在玩的 Seaside 应用程序中使用测试驱动开发,并且我的所有数据都存储为图像中的对象(而不是数据库)。

因此,当我运行测试时,我必须小心存储真实数据,以免它被测试数据破坏,如下所示:

ToDoTest>>setUp 
    savedTasks := Task tasklist.
    Task deleteAllTasks.

    savedProjects := ToDoProject projectlist.
    ToDoProject deleteAllProjects.

    savedPeople := Person peoplelist.
    Person deleteAllPeople.

和:

ToDoTest>>tearDown
    Task tasklist: savedTasks.
    ToDoProject projectlist: savedProjects.
    Person peoplelist: savedPeople

当我的测试失败时问题就来了,当然他们会这样做,这会弹出调试器,然后我可以修复,但并不总是调用 tearDown ,所以我可能会丢失我的真实数据。

我确实将数据保存到文件中,所以这不是一个大问题,但它不像我希望的那样流畅和自动化。

无论如何我可以改善这一点?

4

2 回答 2

6

我不确定是否有可以完全解决问题的方案。真正的问题是模型是全球性的。这既方便又好,但在这种情况下很容易失败。因此,我会考虑将模型从全局更改为更本地化的变体,这样您就可以仅出于测试目的创建模型,而不会干扰生产数据。

要在当前设置中修复它,您需要在某处添加 ensure: block。确保块“确保”您执行某些操作,无论一切正常还是发生错误。问题是您需要在测试之前和之后执行此操作。

在这种情况下,我会在您自己的测试类中用类似的东西覆盖 TestCase>>#runCase

runCase
   [ self saveRealModel.
      super runCase ]
      ensure: [ self restoreRealModel ]
于 2013-04-29T09:46:54.130 回答
2

啊,这是一种很好的测试气味。Norbert 正确地指出您的测试模型可能不应该是全局的。大多数测试应该针对单个对象之间的交互。在 StoryBoard 中,我们有用户

DEUser subclass: #SBUser
    instanceVariableNames: 'email initials projects invitations'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'StoryBoard-Data'

以类 instancevar users 作为入口点。项目只能通过用户访问。

users
    ^users ifNil: [ users := OrderedCollection with: (SBAdministrator new
        userid: 'admin';
        password: 'admin';
        yourself)
    ]

以及清除它们的方法

resetUsers
    " SBUser resetUsers "
    users := nil

通常我们可以传递对域对象创建的依赖项

Iteration>on: aProject
    ^self new
        project: aProject;
        yourself

这允许测试用例本身或单独的(模拟)对象传递

于 2013-05-12T16:36:03.527 回答