Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Add more String.Split tests#1600

Merged
stephentoub merged 1 commit into
dotnet:masterfrom
justinvp:stringsplittests
May 7, 2015
Merged

Add more String.Split tests#1600
stephentoub merged 1 commit into
dotnet:masterfrom
justinvp:stringsplittests

Conversation

@justinvp
Copy link
Copy Markdown
Contributor

Round out String.Split tests in anticipation of #1513.

It's not exhaustive. There are some redundant [InlineData(...)] cases that could probably be removed, but it doesn't really hurt to keep them (these tests are fast) as they do still verify the expected result for those counts.

/cc @ellismg

@justinvp
Copy link
Copy Markdown
Contributor Author

justinvp commented May 1, 2015

Hmm, the build seems to have failed for an unrelated reason...

java.io.IOException: remote file operation failed: d:\j\workspace\dotnet_corefx_windows_release_prtest at hudson.remoting.Channel@4a0926b7:dci-win-fbld-6: java.nio.file.AccessDeniedException: d:\j\workspace\dotnet_corefx_windows_release_prtest\bin\obj\Windows_NT.AnyCPU.Release\Microsoft.CSharp

@justinvp justinvp force-pushed the stringsplittests branch from ebb3e4e to d9f4fd1 Compare May 1, 2015 05:03
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you also include value.Split(',', options) for completeness?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean, also add the following overload?

public string[] Split(char separator, int count);

This would match the existing char[] overload, but there isn't an existing similar overload that just takes a string[] and a count, hence why it was left off for the new overloads.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I edited my above comment for correctness.

You have 6 new overloads in the TemporaryStringSplitExtensions but only 5 assertions in a couple of test cases. I think you're missing a couple of assertions since the number of assertions would be a multiple of 6 per test. In most cases in looks like the tests are missing assertions on one of Split(separator) or Split(separator, options) or both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is verifying that an invalid count throws. The value.Split(',', options) overload doesn't take a count parameter.

@hpshelton
Copy link
Copy Markdown
Contributor

I love the InlineData usage for these; nice job. I'd add a couple more asserts, but looks good to me. 👍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ellismg FYI our internal test system doesn't support Theory so we have to figure out what to do about these.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bummer! I should be able to move all these inline. Let me know.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you keep it as is? I would prefer that we try to write idiomatic tests and have folks like me figure out how to shoehorn them into our internal systems. If it ends up being a pain, I can change this later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is my attempt to get @ellismg to fix our internal system as opposed to stopping folks from using it.

@weshaggard
Copy link
Copy Markdown
Member

@justinvp looks like you added a good number of tests here, which is great but we want to keep our InnerLoop testing to run in less than 5 seconds. How long does it take to run all the tests in this test project? If it takes longer than that we should consider marking the longer running ones as OuterLoop.

@justinvp
Copy link
Copy Markdown
Contributor Author

justinvp commented May 2, 2015

@weshaggard I haven't timed these on CoreCLR, but on desktop they don't take very long.

screen shot 2015-05-02 at 12 00 19 am

@weshaggard
Copy link
Copy Markdown
Member

@justinvp great that should be fine from a timing prospective. Thanks for the data.

@stephentoub
Copy link
Copy Markdown
Member

LGTM

@ellismg
Copy link
Copy Markdown
Contributor

ellismg commented May 6, 2015

LGTM as well, thanks for improving coverage here.

stephentoub added a commit that referenced this pull request May 7, 2015
@stephentoub stephentoub merged commit c4bcd93 into dotnet:master May 7, 2015
@tmat
Copy link
Copy Markdown
Member

tmat commented May 8, 2015

So how do I debug these Theory things? Let's say that one of the cases fails and I want to step thru the case?

@justinvp
Copy link
Copy Markdown
Contributor Author

justinvp commented May 8, 2015

@tmat:

So how do I debug these Theory things? Let's say that one of the cases fails and I want to step thru the case?

Set a (conditional) breakpoint in the [Theory] method.

@tmat
Copy link
Copy Markdown
Member

tmat commented May 8, 2015

I see, so I need to rewrite the content of the InlineData as a condition of the BP. Slightly annoying if it needs to be done multiple times. I fail to see the benefit of this attribute over just a sequence of calls to a test helper method:

TestSplit(",", ',', 0, StringSplitOptions.None, new string[0]);
TestSplit(",", ',', 1, StringSplitOptions.None, new[] { "," });
...

@stephentoub
Copy link
Copy Markdown
Member

The primary benefit of [Theory] from my perspective is that each invocation is treated as its own test, and the xunit tracing of failed tests will include all of the parameter/inline data information for the case that failed. This leads to much better debugging ability when the debugger isn't attached during test execution (in particular when source/line information isn't available).

@tmat
Copy link
Copy Markdown
Member

tmat commented May 8, 2015

@stephentoub Under what circumstances do you not have line information?

@tmat
Copy link
Copy Markdown
Member

tmat commented May 8, 2015

@stephentoub Once your test suite grows a lot, you make a change that affects a lot of tests (likely not this particular case) and need to update the baseline it is actually better to have a single test failure reported in the output than a lot of failed test cases.

@stephentoub
Copy link
Copy Markdown
Member

Under what circumstances do you not have line information?

On Linux/OSX, at least that's the state of things today. But even if it is available, I find it quite helpful to see in the traced failure information exactly what combination of inputs caused things to fail, rather than having to manually track back through each line in the stack trace to see what the various inputs.

With regards to setting breakpoints for debugging, it's also trivial to temporarily comment out all but the [InlineData] elements one cares about, if setting conditional breakpoints is too cumbersome.

need to update the baseline it actually better to have a single test failure

That assumes your baseline is being tracked separately from the source. If you do something like [ActiveIssue] as in corefx, it's still only applied in one place.

@tmat
Copy link
Copy Markdown
Member

tmat commented May 8, 2015

I see. Fair points. I guess we have never needed this since we are able to run tests from VS by right-clicking on them.

"That assumes your baseline is being tracked separately from the source." That's not what I assume. Your baseline is in arguments of the helper:

TestSplit(",", ',', 0, StringSplitOptions.None, new string[0]);
TestSplit(",", ',', 1, StringSplitOptions.None, new[] { "," });

What I meant is that if you have 10 test failures and each has 20 cases, you get 10 errors in output not 200. You'll also get the arguments to the assert equals, so you actually know what values were involved.

@stephentoub
Copy link
Copy Markdown
Member

You'll also get the arguments to the assert equals, so you actually know what failed.

Sure, but often such an assert is deep in the weeds and by itself isn't enough to tell you what the inputs to the higher level test were. You also don't get such help with other asserts like Assert.True.

you get 10 errors in output not 200.

Yes, but there's a flip side to that. Many times in the past I've been bitten thinking I only have one failure left, then I fix it, and once I do more then show up that were hiding behind the previous failure; they weren't getting executed because an assert from a previous test case was firing and preventing their execution.

There are certainly pros and cons to the approach, and I don't think it's a one-size-fits-all, but in a case like this I think it makes a lot of sense.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants