如何使这个函数在Selenium C#中的“foreach循环”可重用?

huangapple go评论72阅读模式
英文:

How can I make this function reusable " foreach loop" in selenium c#?

问题

在上面的循环中,应该可重用,创建了一个Utilities类,不确定如何在需要时调用相同的函数。TIA

英文:
    foreach (Residency residency in test.Residencies)
        {
            if (residency.TestGuid == testGuid)
            {
                if (requiredResidency == null)
                    requiredResidency = residency;
                else if (requiredResidency.StartDate < residency.StartDate)
                    requiredResidency = residency;
            }
        }

the above loop should be reusable, created a Utilities class not sure on how to call the same function in the test when required. TIA

答案1

得分: 1

以下是翻译好的部分:

"requiredResidency" 的声明位置不明确。这使得回答有点困难。

现在,我在实际项目中看到(并执行过)以下操作:

继承

将一组测试共有的功能提取到 "TestBase" 中。

示例:

public abstract class ResidencyTestBase
{
    protected Residency GetRequiredResidency(IEnumerable<Residency> testResidencies, Guid testGuid)
    {
         // TODO 实现
    }
}

// 然后你可以有各种不同的测试类,例如

public class SomeResidencyTest : ResidencyTestBase
{

    [Fact] // 我们使用 xUnit,但这个想法也适用于其他测试框架。
    public void SomeTest()
    {
         var sut = GetRequiredResidency(testData, testId);
// ...
    }
}

public class SomeOtherResidencyTest : ResidencyTestBase
{

    [Fact] // 我们使用 xUnit
    public void SomeOtherTest()
    {
         var sut = GetRequiredResidency(testData, testId);
// ...
    }
}

"TestHelper" 类

示例:

public static class ResidencyTestHelper
{
    // 可以作为测试数据的扩展方法吗?
    public static Residency GetRequiredResidency(this IEnumerable<Residency> testData, Guid testId)
    {
        // 实现
    }
}

// 使用方式
var sut = testData.GetRequiredResidency(testId);

您的具体功能

foreach (Residency residency in test.Residencies)
{
    if (residency.TestGuid == testGuid) // 可以用 LINQ Where 表达
    {
        if (requiredResidency == null)
            requiredResidency = residency; // 副作用!
        else if (requiredResidency.StartDate < residency.StartDate)
            requiredResidency = residency;
        // 缺失情况:两个条件都不符合...
    }
}

因此,我想你可以将其重构如下:

// 作为扩展方法:
// 我们返回引用,因为我们不能依赖副作用
static Residency? GetRequiredResidency(this Residency? requiredResidency,
    IEnumerable<Residency> testData, Guid testId)
{
    // 这里使用了 Linq,但这也可以用传统的语法表示
    var residenciesById = testData.Where(r => r.TestGuid == testGuid);
    if (requiredResidency is not null)
        residenciesById = residenciesById.Where(r => requiredResidency.StartDate < r.StartDate);
    return residenciesById.LastOrDefault() ?? requiredResidency;
    // ^^ 这是为了使行为保持一致。如果两个条件都不满足(= 在您的代码中的 "缺失情况"),我们在这里得到 null,因此我们设置它最初的值。
}

// 使用方式
Residency requiredResidency = ...; // 假设在某处已声明...

requiredResidency = requiredResidency.GetRequiredResidency(test.Residencies, testId);
英文:

It is unclear, where requiredResidency is declared. That makes it a little hard to give an answer.

Now, what I have seen (and done) in actual projects are these:

Inheritance

Functionality, that is common to a set of tests is drawn into a "TestBase".

Example:

public abstract class ResidencyTestBase
{
    protected Residency GetRequiredResidency( IEnumerable&lt;Residency&gt; testResidencies, Guid testGuid )
    {
         // TODO Implementation
    }
}

// and then you&#39;d have various tests like

public class SomeResidencyTest : ResidencyTestBase
{

    [Fact] // we are using xUnit but the idea applies to other 
           // Test Frameworks, too.
    public void SomeTest()
    {
         var sut = GetRequiredResidency( testData, testId );
// ...
    }
}

public class SomeOtherResidencyTest : ResidencyTestBase
{

    [Fact] // we are using xUnit
    public void SomeOtherTest()
    {
         var sut = GetRequiredResidency( testData, testId );
// ...
    }
}

"TestHelper" class(es)

Example:

public static class ResidencyTestHelper
{
    // maybe as extension method on the test data?
    public static Residency GetRequiredResidency(this IEnumerable&lt;Residency&gt; testData, Guid testId)
    {
        // impl.
    }
}

// Usage
var sut = testData.GetRequiredResidency( testId );

Your specific functionality

foreach (Residency residency in test.Residencies)
{
    if (residency.TestGuid == testGuid) // can be expressed as a LINQ Where
    {
        if (requiredResidency == null)
            requiredResidency = residency; // Sideeffect!
        else if (requiredResidency.StartDate &lt; residency.StartDate)
            requiredResidency = residency;
        // Missing case: both conditions fail ...
    }
}

So, I guess one could refactor this like so:

// As ExtensionMethod:
// We _return_ the reference, because we cannot rely on sideeffects
static Residency? GetRequiredResidency ( this Residency? requiredResidency,
    IEnumerable&lt;Residency&gt; testData, Guid testId )
{
// Linq is used here, but this can also be expressed in plain old syntax
    var residenciesById = testData.Where(r =&gt; r.TestGuid == testGuid);
    if( requiredResidency is not null )
        residenciesById = residenciesById.Where(r =&gt;  requiredResidency.StartDate &lt; r.StartDate );
    return residenciesById.LastOrDefault() ?? requiredResidency;
//  ^^ this is to make the behavior the same. If both conditions fail 
//     (= &quot;missing case&quot; in your code, your code does not change the 
//     original, so) we get null here, so we set what it originally was.
}

// Usage
Residency requiredResidency = ...; // Assume declared somewhere...

requiredResidency = requiredResidency.GetRequiredResidency( test.Residencies, testId );

huangapple
  • 本文由 发表于 2023年7月3日 17:49:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定