or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

argument-aggregation.mdargument-conversion.mdcore-testing.mdcsv-sources.mdcustom-sources.mdenum-method-sources.mdindex.mdvalue-sources.md

csv-sources.mddocs/

0

# CSV Data Sources

1

2

Comprehensive CSV data support for inline data and external files with extensive parsing customization options.

3

4

## Capabilities

5

6

### @CsvSource Annotation

7

8

Provides CSV data inline as test arguments with extensive parsing customization.

9

10

```java { .api }

11

/**

12

* Provides CSV data inline as arguments to parameterized tests

13

*/

14

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})

15

@Retention(RetentionPolicy.RUNTIME)

16

@Documented

17

@API(status = STABLE, since = "5.0")

18

@ArgumentsSource(CsvArgumentsProvider.class)

19

@Repeatable(CsvSources.class)

20

@interface CsvSource {

21

/**

22

* Array of CSV records

23

*/

24

String[] value() default {};

25

26

/**

27

* CSV data as text block (Java 15+ syntax)

28

*/

29

String textBlock() default "";

30

31

/**

32

* Use first row as headers in display names

33

*/

34

boolean useHeadersInDisplayName() default false;

35

36

/**

37

* Quote character for escaping

38

*/

39

char quoteCharacter() default '\'';

40

41

/**

42

* Single character delimiter

43

*/

44

char delimiter() default ',';

45

46

/**

47

* Multi-character delimiter string (takes precedence over delimiter)

48

*/

49

String delimiterString() default "";

50

51

/**

52

* Value to use for empty quoted strings

53

*/

54

String emptyValue() default "";

55

56

/**

57

* Custom strings that represent null values

58

*/

59

String[] nullValues() default "";

60

61

/**

62

* Maximum characters per column (protection against malformed data)

63

*/

64

int maxCharsPerColumn() default 4096;

65

66

/**

67

* Whether to trim whitespace from unquoted values

68

*/

69

boolean ignoreLeadingAndTrailingWhitespace() default true;

70

}

71

```

72

73

**Usage Examples:**

74

75

```java

76

import org.junit.jupiter.params.ParameterizedTest;

77

import org.junit.jupiter.params.provider.CsvSource;

78

79

class CsvSourceExamples {

80

81

// Basic CSV data

82

@ParameterizedTest

83

@CsvSource({

84

"1, apple, true",

85

"2, banana, false",

86

"3, cherry, true"

87

})

88

void testBasicCsv(int id, String name, boolean active) {

89

assertTrue(id > 0);

90

assertNotNull(name);

91

}

92

93

// Custom delimiter

94

@ParameterizedTest

95

@CsvSource(value = {

96

"1|apple|red",

97

"2|banana|yellow",

98

"3|cherry|red"

99

}, delimiter = '|')

100

void testCustomDelimiter(int id, String fruit, String color) {

101

assertTrue(id > 0);

102

assertNotNull(fruit);

103

assertNotNull(color);

104

}

105

106

// Multi-character delimiter

107

@ParameterizedTest

108

@CsvSource(value = {

109

"apple::red::sweet",

110

"lemon::yellow::sour"

111

}, delimiterString = "::")

112

void testMultiCharDelimiter(String fruit, String color, String taste) {

113

assertNotNull(fruit);

114

assertNotNull(color);

115

assertNotNull(taste);

116

}

117

118

// Quoted values with commas

119

@ParameterizedTest

120

@CsvSource({

121

"'John Doe', 'San Francisco, CA', 94102",

122

"'Jane Smith', 'New York, NY', 10001"

123

})

124

void testQuotedValues(String name, String city, int zipCode) {

125

assertTrue(name.contains(" "));

126

assertTrue(city.contains(","));

127

assertTrue(zipCode > 0);

128

}

129

130

// Null and empty value handling

131

@ParameterizedTest

132

@CsvSource(value = {

133

"apple, , sweet", // Empty middle value

134

"banana, yellow, ", // Empty last value

135

"cherry, red, NIL" // Custom null value

136

}, nullValues = {"NIL"}, emptyValue = "EMPTY")

137

void testNullAndEmptyValues(String fruit, String color, String taste) {

138

assertNotNull(fruit);

139

// color and taste may be null or "EMPTY"

140

}

141

142

// Headers in display names

143

@ParameterizedTest(name = "Product: {arguments}")

144

@CsvSource(value = {

145

"ID, Name, Price",

146

"1, Apple, 1.50",

147

"2, Banana, 0.75"

148

}, useHeadersInDisplayName = true)

149

void testWithHeaders(String id, String name, String price) {

150

assertNotNull(id);

151

assertNotNull(name);

152

assertNotNull(price);

153

}

154

155

// Text block syntax (Java 15+)

156

@ParameterizedTest

157

@CsvSource(textBlock = """

158

1, apple, 1.50

159

2, banana, 0.75

160

3, cherry, 2.00

161

""")

162

void testTextBlock(int id, String fruit, double price) {

163

assertTrue(id > 0);

164

assertNotNull(fruit);

165

assertTrue(price > 0);

166

}

167

168

// Whitespace handling

169

@ParameterizedTest

170

@CsvSource(value = {

171

" apple , red ", // Whitespace will be trimmed

172

"' banana ', yellow" // Quoted whitespace preserved

173

}, ignoreLeadingAndTrailingWhitespace = true)

174

void testWhitespaceHandling(String fruit, String color) {

175

// apple will be trimmed, " banana " will preserve spaces

176

assertNotNull(fruit);

177

assertNotNull(color);

178

}

179

}

180

```

181

182

### @CsvFileSource Annotation

183

184

Loads CSV data from classpath resources or file system files.

185

186

```java { .api }

187

/**

188

* Loads CSV data from external files as arguments to parameterized tests

189

*/

190

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})

191

@Retention(RetentionPolicy.RUNTIME)

192

@Documented

193

@API(status = STABLE, since = "5.0")

194

@ArgumentsSource(CsvFileArgumentsProvider.class)

195

@Repeatable(CsvFileSources.class)

196

@interface CsvFileSource {

197

/**

198

* Classpath resources to load CSV data from

199

*/

200

String[] resources() default {};

201

202

/**

203

* File system paths to load CSV data from

204

*/

205

String[] files() default {};

206

207

/**

208

* Character encoding for file reading

209

*/

210

String encoding() default "UTF-8";

211

212

/**

213

* Line separator for parsing

214

*/

215

String lineSeparator() default "\n";

216

217

/**

218

* Number of lines to skip from beginning (e.g., headers)

219

*/

220

int numLinesToSkip() default 0;

221

222

// Inherits all parsing attributes from @CsvSource

223

boolean useHeadersInDisplayName() default false;

224

char quoteCharacter() default '"';

225

char delimiter() default ',';

226

String delimiterString() default "";

227

String emptyValue() default "";

228

String[] nullValues() default "";

229

int maxCharsPerColumn() default 4096;

230

boolean ignoreLeadingAndTrailingWhitespace() default true;

231

}

232

```

233

234

**Usage Examples:**

235

236

```java

237

import org.junit.jupiter.params.ParameterizedTest;

238

import org.junit.jupiter.params.provider.CsvFileSource;

239

240

class CsvFileSourceExamples {

241

242

// Load from classpath resource

243

@ParameterizedTest

244

@CsvFileSource(resources = "/test-data/products.csv")

245

void testFromClasspathResource(int id, String name, double price) {

246

assertTrue(id > 0);

247

assertNotNull(name);

248

assertTrue(price >= 0);

249

}

250

251

// Load from file system

252

@ParameterizedTest

253

@CsvFileSource(files = "src/test/resources/users.csv")

254

void testFromFile(String username, String email, int age) {

255

assertNotNull(username);

256

assertTrue(email.contains("@"));

257

assertTrue(age >= 0);

258

}

259

260

// Skip header rows

261

@ParameterizedTest

262

@CsvFileSource(

263

resources = "/test-data/products-with-headers.csv",

264

numLinesToSkip = 1

265

)

266

void testSkipHeaders(int id, String name, double price) {

267

assertTrue(id > 0);

268

assertNotNull(name);

269

assertTrue(price >= 0);

270

}

271

272

// Custom encoding and delimiter

273

@ParameterizedTest

274

@CsvFileSource(

275

resources = "/test-data/international.csv",

276

encoding = "UTF-8",

277

delimiter = ';'

278

)

279

void testCustomEncodingAndDelimiter(String name, String country, String currency) {

280

assertNotNull(name);

281

assertNotNull(country);

282

assertNotNull(currency);

283

}

284

285

// Multiple files

286

@ParameterizedTest

287

@CsvFileSource(resources = {

288

"/test-data/products-q1.csv",

289

"/test-data/products-q2.csv"

290

})

291

void testMultipleFiles(int id, String name, double price) {

292

assertTrue(id > 0);

293

assertNotNull(name);

294

assertTrue(price >= 0);

295

}

296

297

// With custom null values

298

@ParameterizedTest

299

@CsvFileSource(

300

resources = "/test-data/incomplete-data.csv",

301

nullValues = {"N/A", "NULL", ""}

302

)

303

void testWithNullValues(String name, String value, String category) {

304

assertNotNull(name); // name should never be null

305

// value and category may be null based on nullValues

306

}

307

}

308

```

309

310

### CSV Parsing Exception

311

312

Exception thrown when CSV parsing fails due to malformed data or configuration issues.

313

314

```java { .api }

315

/**

316

* Exception thrown when CSV parsing fails

317

*/

318

@API(status = STABLE, since = "5.0")

319

class CsvParsingException extends JUnitException {

320

/**

321

* Constructs exception with message

322

*/

323

CsvParsingException(String message) { }

324

325

/**

326

* Constructs exception with message and cause

327

*/

328

CsvParsingException(String message, Throwable cause) { }

329

}

330

```

331

332

### Container Annotations

333

334

Container annotations for multiple CSV source annotations.

335

336

```java { .api }

337

/**

338

* Container annotation for multiple @CsvSource annotations

339

*/

340

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})

341

@Retention(RetentionPolicy.RUNTIME)

342

@Documented

343

@API(status = STABLE, since = "5.0")

344

@interface CsvSources {

345

CsvSource[] value();

346

}

347

348

/**

349

* Container annotation for multiple @CsvFileSource annotations

350

*/

351

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})

352

@Retention(RetentionPolicy.RUNTIME)

353

@Documented

354

@API(status = STABLE, since = "5.0")

355

@interface CsvFileSources {

356

CsvFileSource[] value();

357

}

358

```

359

360

**Advanced CSV Features:**

361

362

```java

363

class AdvancedCsvExamples {

364

365

// Complex CSV with various data types

366

@ParameterizedTest

367

@CsvSource({

368

"1, 'Product A', 19.99, true, 2023-01-15",

369

"2, 'Product B', 29.50, false, 2023-02-20",

370

"3, 'Product \"Special\"', 39.99, true, 2023-03-10"

371

})

372

void testComplexCsv(int id, String name, double price, boolean available, String date) {

373

assertTrue(id > 0);

374

assertNotNull(name);

375

assertTrue(price > 0);

376

assertNotNull(date);

377

}

378

379

// Handling special characters and escaping

380

@ParameterizedTest

381

@CsvSource(value = {

382

"apple|'red, juicy'|1.50",

383

"banana|yellow|0.75",

384

"cherry|'dark red'|2.00"

385

}, delimiter = '|')

386

void testSpecialCharacters(String fruit, String description, double price) {

387

assertNotNull(fruit);

388

assertNotNull(description);

389

assertTrue(price > 0);

390

}

391

}

392

```

393

394

The CSV sources provide powerful data-driven testing capabilities with fine-grained control over parsing behavior, making them ideal for complex test scenarios with structured data.