15

What tests should I use to unit test a CSV parser?

I have a simple CSV parser in C#, and I want to be sure that I have good unit test coverage of all the common (and uncommon) edge cases. What tests should I use to identify potential problems and boundary cases?

5
  • 5
    Have you checked generatedata.com for the creation of varying test files? Apr 4, 2011 at 19:47
  • @Aaron - good tests are repeatable, and therefore don't use data that varies. But I could perhaps use them for a one-off generation that I then save for a test suite. But even then, I want to make sure I've covered all the different edge cases, which random is not guaranteed to do. Apr 4, 2011 at 19:53
  • 1
    Coehorn Good test outcomes are repeatable. I'd argue that using data that varies is fine so long as the desired outcome remains constant. If you want to make sure you have covered all the different edge cases (based on your comments you appear certain what those are) why not start writing the tests? You will spend more time looking for a magical solution then simply writing the tests. Apr 4, 2011 at 20:12
  • 1
    The author is looking for test cases, not test data. I wish I knew where to find public tests for various things, too.
    – ProdigySim
    Apr 4, 2011 at 22:14
  • 1
    If you don't understand the cases that you need to test for; how are you assuming that you even knew what to develop to begin with? Logically, you should be able to write test cases for the scenario's that you actually covered with your implementation. The real question you're asking here is what business requirements you should have come up with at the analysis stage.
    – Flater
    Sep 4 at 0:58

5 Answers 5

7

I just found https://github.com/maxogden/csv-spectrum:

A bunch of different CSV files to serve as an acid test for CSV parsing libraries. There are also JSON versions of the CSVs for verification purposes.

The goal of this repository is to capture test cases to represent the entire CSV spectrum.

2
18

Here are a few boundary cases that you should have thought through and have test cases for.

  1. Basic field. ,foo,
  2. Basic quoted field. ,"foo",
  3. Quoted field with embedded newline. ,"foo\nbar"
  4. Quoted field with embedded comma. ,"foo,bar"
  5. Quoted field with embedded quote. ,"foo""bar"
  6. Do you distinguish between empty strings and nulls? If you do then ,, should be a null and ,"", should give an empty string.
  7. Do you try to detect data types and do the right thing? CSV is often used for numerical data. Add whatever tests you think appropriate for that.
  8. If you write data, you should cover all of the above cases.
  9. What do you do with lines with different numbers of fields? (Test it.)
  10. What do you do with trailing blank lines? (Test it.)
  11. How is performance on a large file? (Test it. I've seen too many homegrown CSV parsers that use strings inefficiently and as a result take quadratic time, leading to simple stuff becoming painfully slow.)
10

There is no formal specification for CSV files. However, take a look at RFC 4180 - Common Format and MIME types for CSV files, (particularly Section 2) which documents the format that seems to be followed by most implementations.

It seems fairly straightforward to start generating some test cases from the list in section 2, specifically:

  1. Each record is located on a separate line, delimited by a line break (CRLF). For example:

    aaa,bbb,ccc CRLF zzz,yyy,xxx CRLF

  2. The last record in the file may or may not have an ending line break. For example:

    aaa,bbb,ccc CRLF zzz,yyy,xxx

  3. There maybe an optional header line appearing as the first line of the file with the same format as normal record lines. This header will contain names corresponding to the fields in the file and should contain the same number of fields as the records in the rest of the file (the presence or absence of the header line should be indicated via the optional "header" parameter of this MIME type). For example:

    field_name,field_name,field_name CRLF aaa,bbb,ccc CRLF zzz,yyy,xxx CRLF

  4. Within the header and each record, there may be one or more fields, separated by commas. Each line should contain the same number of fields throughout the file. Spaces are considered part of a field and should not be ignored. The last field in the record must not be followed by a comma. For example:

    aaa,bbb,ccc

  5. Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes at all). If fields are not enclosed with double quotes, then double quotes may not appear inside the fields. For example:

    "aaa","bbb","ccc" CRLF zzz,yyy,xxx

  6. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes. For example:

    "aaa","b CRLF bb","ccc" CRLF zzz,yyy,xxx

  7. If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote. For example:

    "aaa","b""bb","ccc"

8

The US census data is available in CSV

I've been working on it for a while. It's certainly weird enough to be a good test, and there is tons and tons of it.

1
  • would you mind explaining more on what it does and why do you recommend it as answering the question asked? "Link-only answers" are not quite welcome at Stack Exchange
    – gnat
    Jul 25, 2013 at 5:20
4

Check this directory out and look at the code in the *.t files.:

http://cpansearch.perl.org/src/MAKAMAKA/Text-CSV-1.32/t/

(The version number -1.32 might change eventually so the link might become "dead". Increment the version number yourself by trial-and-error, or go to the parent directory or click here

https://metacpan.org/pod/Text::CSV

and click through via "Browse" to the source code of the newest version)

Text::CSV_XS is a mature perl module for parsing csv files. The *.t files are written in Perl 5, they contain lots of testcases for self-testing the module, they are to be performed at module installation time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.