您如何测试您的业务对象?

发布于 2024-07-13 14:17:56 字数 708 浏览 9 评论 0原文

我想使用 Visual Studio 中的 Microsoft 测试框架为我的软件开发项目实施自动化测试。 我创建了一些测试,总而言之,它非常容易使用。

对于测试业务对象(更具体地说是读取和写入数据库的业务对象),有哪些更好的实践

是否最好从测试用户界面的开发数据库中设置一个单独的测试数据库,然后仅针对该数据库进行测试? 基本上只是用垃圾数据填充它。

是否最好接受某种类型的清理心态,也就是说,如果我正在测试 AddUser 方法,我是否添加用户,检查我的测试,然后删除用户?

您是否在单个测试方法中测试每个 CRUD 方法?

最后,个人业务规则如何,例如验证字符串大小是否正确、开始日期小于结束日期、CustomerId 是否是正确的客户等等。

我意识到这是一个相当广泛的问题......只是寻找一些方向......采取小步骤。

更多信息...

很多很好的答案! 我不确定我是否能够建立一个模拟数据库。 我使用 CSLA 作为我的对象的框架。 需要进行一些认真的重构才能使用模拟对象进行测试。 我要调查一下。 不过,在某些时候,我确实想要测试数据库交互......使用模拟数据库时,您将在何处/何时实际测试数据库通信?

另一个问题……最好让每种测试方法不依赖于其他测试吗?

I am wanting to implement automated testing, using the Microsoft testing framework in Visual Studio, for my software development projects. I have created some tests, and all in all, it's pretty easy to use.

What are some better practices for testing business objects, more specifically ones that read and write to a database.

Is it best to setup a separate test database, from the development database, where the user interface is tested from, and just test against that database? Basically just filling it with junk data.

Is it better to embrace some type of clean-up after yourself mentality, meaning, if I am testing the AddUser method, do I add the User, check my tests, and then delete the User?

Do you test each of the CRUD methods in a single test method?

Lastly, what about the individual business rules like verifying strings are of the correct size, start dates are less than end dates, the CustomerId is a correct Customer and so on.

I realize this is a pretty broad question ... just looking for some direction ... taking baby steps.

More information...

Lot's of good answers! I'm not sure I would be able to pull off a mock database. I am using CSLA as the framework for my objects. It would take some serious refactoring to make this testable with mock objects. I'm going to look into this. Though, at some point, I do want to test the database interaction ... when using a mock database, where/when would you actually test the database communication?

One other question ... is it best to keep each test method non-dependent on other tests?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

财迷小姐 2024-07-20 14:17:56

理想情况下,您的业务对象不直接访问数据库,而是使用辅助对象或某种 ORM(对象关系映射)框架。 然后,您可以在没有数据库的情况下测试您的 BO,可能会模拟一些辅助对象。 这可能是最干净的方法,因为您避免了真实数据库的复杂性,并且实际上只测试您的业务逻辑。

如果您无法避免将业务规则和数据库访问合并到一个类中(可能是一种有问题的设计,但有时很难避免),那么您必须针对数据库进行测试。

几乎唯一合理的选择是拥有一个单独的数据库用于自动测试。 您的测试方法应该删除设置中的所有内容,然后加载所有数据,进行测试并验证结果。

甚至不要考虑尝试初始化数据库一次然后运行所有
对相同数据进行测试。 一项测试会意外更改数据,并且
其他测试会神秘地失败。 我已经这么做了并且后悔了...
每个测试都必须独立存在。

为了做到这一切,我强烈推荐某种数据库测试框架。
这些可以帮助您清理数据库、加载必要的数据以及比较查询
结果达到预期结果。
我使用 DBUnit(用于 Java),但还有许多其他用于其他语言的。

Ideally, you would have business objects that do not directly access the database, but use helper objects or some kind of ORM (Object-relational mapping) framework. Then you can test your BOs without a database, possibly mocking some helper objects. That is probably the cleanest way, because you avoid the complexity of a real DB, and really only test your business logic.

If you cannot avoid combining business rules and DB access into one class (probably a problematic design, but sometimes hard to avoid), then you have to test against a DB.

There pretty much the only reasonable option is to have a separate DB for automatic testing. Your test methods should delete everything on setup on setup, then load all their data, do the test and verify results.

Don't even think about trying initialise the DB once and then run all
tests on the same data. One test will accidentally change data, and
other tests will mysteriously fail. I've done that and regretted it...
Each test really must stand on its own.

To do all this, I strongly recommend some kind of DB testing framework.
These help you to clean the DB, load necessary data, and compare query
results to expected results.
I use DBUnit (for Java), but there are many others for other languages.

若言繁花未落 2024-07-20 14:17:56

我建议实现您的业务对象,以便它们不知道数据库。 使用数据访问层上的方法,可以根据业务对象的类型正确保存/检索业务对象(即,它在表和它们对应的对象之间具有内部映射)。 当测试业务对象本身时,您根本不必担心数据库。 只需创建对象,也许使用反射来设置私有字段,然后对对象进行测试。

当测试需要与数据访问层交互的代码时,使用模拟创建模拟数据层并对其设置期望以返回所需的对象或正确响应保存。 您可能需要将数据层开发为接口(或者如果使用不直接支持模拟的严格框架,则将其包装为可模拟类)。 大多数模拟框架要求方法是虚拟的,以允许创建模拟实现。 使用接口强制实现类中的方法是虚拟的,因此模拟更容易。

I would recommend implementing your business objects so that they are unaware of the database. Use methods on the data access layer that can save/retrieve business objects properly depending on their type (i.e., it has an internal mapping between the tables and the objects they correspond to). When testing your business object itself, then you need not worry about the database at all. Simply create the object, perhaps use reflection to set private fields, and conduct your test on the object.

When testing code that needs to interact with the data access layer, use mocking to create a mock data layer and set up expectations on it to return the desired objects or respond properly to saves. You may need to develop your data layer to an interface (or wrap it with a mockable class if using a rigid framework that doesn't support mocking directly). Most mocking frameworks require that methods be virtual to allow a mock implementation to be created. Using interfaces forces the methods in the implementing class to be virtual so mocking is much easier.

不交电费瞎发啥光 2024-07-20 14:17:56

使用依赖注入。 在接口中实现数据库方法。 然后用控制数据编写一个新的接口实现来测试适用的场景。

Use dependency injection. Implement your database methods in an interface. Then write a new implementation of the interface with control data to test the applicable scenarios.

甜味拾荒者 2024-07-20 14:17:56

有关 TDD 和 CSLA 的更多信息可以在此问题的答案中找到。 尤其是这个

另外这个问题可能很有趣。

More info about TDD with CSLA can be found in the answers to this question. Especially this one.

Also this question might be interesting.

我的黑色迷你裙 2024-07-20 14:17:56

一般来说,我创建 BO,将其保存到夹具设置中的数据库中,然后对各种插入/更新/选择进行测试,然后在我的拆卸中从数据库中删除对象。 它使事情保持良好和干净,特别是当涉及很多约束时,如果您不删除在测试中创建的所有内容,您的测试数据库可能会很快变得混乱。

Generally I create the BO, save it to the db in the fixture setup, then have tests for various insert/update/selects then in my teardown delete the object from the database. It keeps things nice and clean especially when lots of constraints are involved, your test db can get messy real quick if you don't remove everything you create in your tests.

风铃鹿 2024-07-20 14:17:56

要测试数据库访问层,您不应在同一数据库上运行所有测试。 某些测试可能会失败,因为它们依赖于其他测试的结果。 所以这不是你想要的。 实际上,每次测试后,您都应该将数据库状态恢复到测试运行之前的原始状态。

在我的实践中,我将测试数据集保存在 XML 中,并且在每次测试之前,它使用 XML 在 db 中设置数据。 因此,每个测试都针对某个数据集运行。

To test DB Access Layer, you should not run all tests on same db. Some tests may fail because they depend on the results of other test. So this is not what you want. Actually after every test, you should return the db status to the original status before the test runs.

In my practice, I keep the test data set in a XML and before every test, it setup the data in db using the XML. So every test runs against some dataset.

妳是的陽光 2024-07-20 14:17:56

我支持曾经说过的一句话:您应该使用 moched 数据库来测试业务对象。 在某些情况下,您可能希望将数据保留为测试的一部分。 这样做的缺点是运行测试时间较长并且需要清理。

一种可能对您有所帮助的解决方案是使用内存数据库进行测试。 例如,SQLite 允许您动态创建内存数据库,当您处置它们时,它们就会消失。 这使您的测试速度更快,并且您不必设置清理代码 - 而您实际上可以通过自动化测试来测试您的 SQL/数据库代码。

I support the once saying that you should test you business objects with a moched database. In some cases you might want to have your data persisted as part of the test though. The drawbacks to this are longer running tests and the need for cleanup.

One solution to this that might help you is to use an in-memory database for your tests. SQLite for instance lets you create in-memory databases on the fly, and when you dispose them they are gone. This makes your tests much faster, and you don't have to set up cleanup code - while you actually get to test your SQL / db code through automated tests.

别把无礼当个性 2024-07-20 14:17:56

(我知道您不使用 Java,但下面的一般策略根本不依赖于 Java)

我正在开发一个使用大量 EJB3/JPA 代码的 Java 项目。 我决定创建一种模拟容器,能够“部署”EJB 并将内存数据库 (HSQL) 与 hibernate 实体管理器结合使用。

这个“容器”启动时间不到 1 秒,允许我测试大多数业务组件,包括那些通过 JPA 访问数据库的组件。 例如,如果某个服务太复杂而无法支持,那么我只需使用 EasyMock(或任何其他模拟库)来创建一个假服务并插入“容器”中。

到目前为止,它取得了巨大的成功,但需要我几天的时间来实现模拟基础设施。

(I know you don´t use Java but the general strategy below does not depend on Java at all)

I'm working on a Java project that uses a lot of EJB3/JPA code. I decided to create a kind of mock container able to "deploy" EJBs and use an in-memory database (HSQL) with hibernate entity manager.

This "container" starts up in less than 1 second and allows me to test most business components, including those that access the database via JPA. If a service is, for example, too complex to support then I simply use EasyMock (or any other mock library) to create a fake service and plug in into the "container".

It's been a huge success so far, but required me a couple of days to implement the mock infrastructure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文