Skip to content
DannoHung edited this page Sep 13, 2010 · 9 revisions

Fixtures provide a convenient and simple way of getting data into your tests without cluttering the test code with a bunch of literals. There are three distinct types of fixtures that can be used:

  • A Q object saved to disk as a file
  • A directory containing splayed tables and/or partitioned tables
  • A specially formatted separated value file (like a csv, but slightly different)

Like the mock function, the fixture functions are unloaded after they have been used and in the case of directory fixtures, if a partition had been previously loaded, it will be restored after the test has run.

There are two methods used for loading fixtures that are closely related:

fixture and fixtureAs

fixture is a function which takes one argument: A symbol specifying the name of the fixture to be loaded. This will cause the fixture specified by that name to be loaded into the current namespace as the name specified if the fixture is a Q object file or a separated value file. If the fixture is a directory containing splayed or partitioned tables, then the directory will be loaded as if the \l directive was used with the directory path.

So, for example, supposing we have three different fixtures: foo, bar and baz. foo is a Q object file, bar is a separated value file, and baz is a directory:


q)fixture `foo
`foo
q)foo
1 2 3 4 5
q)fixture `bar
`bar
q)bar
a b
---
1 3
2 4
3 5
q)\a
,`bar
q)fixture `baz
`baz
q)\a
`bar`trade`quote

Please note that for this example and others on this page, we are ignoring that you would need to have written a test to actually be able to use the functions presented. To see a more concrete example of this feature, please see the Tutorial

fixtureAs is a function which takes two arguments: The first argument is the name of the fixture to be loaded and the second argument is a name to assign the fixture to as opposed to the default. If the fixture is a directory, the second argument is ignored.

Two paths are searched for fixtures: the directory where the test file was loaded from and a directory fixtures in the directory where the test file was loaded from if available. So, for example, if you were loading a fixture trade, you could have a test in /abc/def and both /abc/def and /abc/def/fixtures would be searched for the fixture.

Q File Object Fixtures

A Q file object fixture is simply any Q object that has been saved to disk. Tables, dictionaries, lists, and atoms all; anything that can be written to the filesystem. In addition to strict file objects, a single splayed directory is also treated as if it were a file object. We will attempt to illustrate this difference.

If you were using a fixture object in a test, you would likely have collected the data from some source beforehand and then saved it with your tests. In the following example, we’ll save a few objects and load them as fixtures:


q)`:foo set ([]a:1 2 3;b:4 5 6)
`:foo
q)`:bar/ set ([]c:"abc";d:7 8 9) / Note that this is a single splayed table
`:bar/
q)`:baz set 0 1 2 3 4 5 6 7 8 9
`:baz
q)fixture `foo
`foo
q)foo
a b
---
1 4
2 5
3 6
q)bar
c d
---
a 7
b 8
c 9
q)baz
0 1 2 3 4 5 6 7 8 9

Directory Fixtures

A directory fixture is fundamentally a partitioned directory which could contain a number of partitioned tables in addition to splayed tables as is commonly seen when working with Q. Because loading a partition involves potentially many tables, the name of the fixture is ignored except for finding the relevant directory (this also follows for fixtureAs).

In this example, we have three partitioned directories: taq, foo, and qux.


q)\l taq
q)\a
`trade`quote
...
/ Begin running tests afer this point
...
q)fixture `foo
q)\a
`bar`baz
q)fixture `qux
q)\a
`quux`quuux
...
/ Tests have finished
...
q)\a
`trade`quote

Separated Value File Fixtures

The separated value file fixtures differ slightly from the other two types in that they do not precisely match existing elements of Q, though they are not that far removed. Put simply, separated value file fixtures are tabular text files where the values are separated by comma, pipe, space, semicolon, or any other character also containing a type format line at the top of the file.

This is best illustrated by an example; here we have a file foo.csv:


D,T,S,F,I,S
date, time, sym, price, size, ex
2009-05-20,09:30:01,IBM,98.3,200,NYS
2009-05-20,09:30:34,MSFT,18.3,100,NYS
2009-05-20,09:32:01,IBM,98,300,NYS
2009-05-20,09:34:01,IBM,97.2,100,NYS
2009-05-20,09:30:01,MSFT,18.34,200,NYS

So, with the exception of the first line, this is a pretty normal looking csv that you might load with 0:. In fact, you might notice that the first line simply contains the string casting literals that are usd with $. This is how the types of the data are determined.

The format of the first line is fairly important. In addition to setting the types of the columns to be loaded, the second character used is inferred to be the delimiter for the rest of the file. If this is a comma, then the file inferred to be comma separated, if it is a pipe, then it is pipe separated, if it is a tab, then it is tab separated.

Finally, it is also important that these files have a dot file extension of some sort. This is the criteria that is used to infer that a fixure is a separated value file as opposed to a Q object file. You should not refer to the extension when loading the fixture though.

All that said, if we load the fixture, it looks just as you would expect it:


q)fixture `foo
`foo
q)foo
date       time         sym  price size ex
-------------------------------------------
2009.05.20 09:30:01.000 IBM  98.3  200  NYS
2009.05.20 09:30:34.000 MSFT 18.3  100  NYS
2009.05.20 09:32:01.000 IBM  98    300  NYS
2009.05.20 09:34:01.000 IBM  97.2  100  NYS
2009.05.20 09:30:01.000 MSFT 18.34 200  NYS

Clone this wiki locally