【问题标题】:Correct design for certain methods某些方法的正确设计
【发布时间】:2015-04-16 13:48:33
【问题描述】:

假设你有一个班级RunMe。顾名思义,它是由另一个类运行的。让我们假设通过RunMe.run()

RunMe 有一个带有 Data 的私有变量,用于运行不同的测试,让我们调用 ist data。 假设这个数据是由RunMe.initialize()初始化的。

之后,在run() 方法中,使用initialize 函数为data 设置的默认值运行第一个测试。让我们称这个测试方法为testWithDefaultValues

我们现在想用一些自定义数据填充我们的data。假设我们使用fillData 执行此操作。

然后我们想使用我们新填充的数据执行另一个测试。让我们将此测试称为testWithFilledData

此时我们的运行方法看起来像这样

public void run() {
  initialize();
  testWithDefaultValues();
  fillData();
  testWithFilledData();
}

你能看出这段代码看起来有多尴尬吗?它看起来和感觉都错了。一件事直接进入我的脑海:testWithFilledData()testWithDefaultValues() 的唯一原因实际上是按照名称假设的那样做,因为这些函数在run 中调用的顺序。这一定是错误的。

所以我应该消除initializefillData 并在相应的测试功能中执行这些功能吗?

如果您考虑到将存在更多测试功能,每个测试功能都使用不同的数据集进行测试,所有这些都必须完全手动填充 (data.setField("fooField","fooValue);)。

有人能给出一个一般性的构想或想法,解释他将如何正确解决给定的任务吗?

现在我真的很难找到一种“感觉不错”且正确的模式。我现在做的一定是错的。

编辑:值得一提的是,测试功能不能是通用的。对于data 的每个不同变体,必须考虑不同的结果。

【问题讨论】:

  • 你为什么要调用一个类RunMe?类的实例有什么作用?
  • 这个类实际上并不叫RunMe,它只是一个例子。它是 Selenium 测试套件的一部分。另一个类应该运行大量的 Selenium-Tests(对于网站上存在的所有逻辑过程)。每个类(例如本例中的 RunMe)都在说明这种测试。所以类不是在测试自己,类是测试。

标签: java selenium testing


【解决方案1】:

好吧,如果您尝试调用testWithDefaultValues() 而不先调用initialize() 会发生什么?您实际上不会使用默认值进行测试,您将使用之前设置的数据进行测试。我认为您应该远离在实际测试函数中修改内部测试数据,而应该拥有一个将 data 传递到其中的通用测试函数。

如果 testWithDefaultValues()testWithFilledData() 实际上在做同样的事情但使用不同的数据,这很有意义。

我认为这样的事情更有意义:

Data testData = getTestData();
test(testData);
Data fillData = getFillData();
test(fillData);

【讨论】:

  • 是的,这就是我所看到的。但是,考虑到您必须针对 20 种不同的数据变体测试数据集。你会为 20 个不同的数据集创建 20 个不同版本的函数吗? test() 也不能是通用的。我没有提到这一点。每个测试都必须考虑不同的结果。函数 testWithDefaultValues() 必须考虑不同于 testWithFilledData();
  • 即使它不能是通用的,你也不应该依赖其他测试方法可以修改的内部数据属性。
【解决方案2】:

我认为您应该只使用一种方法来填充您尝试实现的测试所需的所有代码。然后,您可以相应地为您的测试填写variablesdata,并为您的data 设置不同的值,以便始终从相同的方法开始运行不同的测试。

通过这个简单的结构,您可以创建多个测试方法并且不会迷失在代码中。

编辑

您应该始终考虑像黑盒测试这样的测试方法。如果您认为您不知道方法中运行的代码是什么。您只需要关心测试中的inputoutput

如果相同的方法应该基于不同的input产生不同的output。黑盒内的代码保持不变。

但是,如果您的方法需要与 input 进行不同的交互以生成所需的 output,那么,您需要考虑编写不同的测试。

我的两分钱,希望对你有帮助

【讨论】:

  • 这绝对是正确的做法,但请考虑我的编辑。我没有提到每个测试函数都必须检查不同的结果,这取决于 data 的填充方式。
【解决方案3】:

我建议使用模板方法设计模式来创建测试框架。使用 JUnit 等成熟的测试框架可能会更好。

public abstract class TestCase {
    // This is the template method.
    public final boolean execute() {
        initTest();
        return runTest();
    }

    // Init hook method.
    public abstract void initTest();

    // Test logic hook method.
    public abstract boolean runTest();
}

public abstract class BaseTest extends TestCase {
    public boolean runTest() {
        // This is the common execution for different data sets...
    }
}

public Test1 extends BaseTest {
    public void initTest() {
        // Data init for test 1...
    }
}

您可以为您拥有的每个测试数据集扩展BaseTest。运行测试:

new Test1().execute();
new Test2().execute();

编辑:如果您没有通用测试逻辑,您当然可以跳过BaseTest。或者,您可以定制模板方法以添加更多钩子,以满足您的特定需求。重点是在模板方法中捕获公共进程,在一些钩子方法中隔离公共代码,在其他钩子方法中提供唯一的具体覆盖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    相关资源
    最近更新 更多