• Stars
    star
    212
  • Rank 186,122 (Top 4 %)
  • Language
    Shell
  • License
    GNU Affero Genera...
  • Created about 12 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Shell tests

The repository at https://github.com/tlevine/urchin will go away. New location is https://git.sdf.org/tlevine/urchin.

                   __    _     
  __  ____________/ /_  (_)___ 
 / / / / ___/ ___/ __ \/ / __ \
/ /_/ / /  / /__/ / / / / / / /
\__,_/_/   \___/_/ /_/_/_/ /_/ 

Urchin is a portable shell program that runs a directory of Unix-style programs and produces pretty output. It is normally used for testing shell programs, where each test case corresponds to a single file in the directory that Urchin runs.

Urchin is called "Urchin" because sea urchins have shells called "tests".

Try it out

Urchin's tests are written in Urchin, so you can run them to see what Urchin is like. Clone the repository

git clone https://git.sdf.org/tlevine/urchin

Run the tests

cd urchin
./urchin tests

Dependencies

Urchin depends on the following programs.

  • sh
  • echo
  • printf
  • mktemp
  • readlink
  • basename
  • dirname
  • sed
  • grep
  • cut
  • true
  • false
  • which
  • timeout
  • sort

Vanilla installations of modern BSD and GNU systems usually include all of these programs.

Install

Urchin is contained in a single file, so you can install it by copying it to a directory in your PATH. For example, you can run the following as root.

cd /usr/local/bin
wget https://git.sdf.org/tlevine/urchin/raw/branch/master/urchin
chmod +x urchin

Urchin can be installed with npm too.

npm install -g urchin

Now you can run it.

urchin <test directory>

Run urchin -h to get command-line help.

Writing tests

Make a root directory for your tests. Inside it, put executable files that exit 0 on success and something else on fail. Non-executable files and hidden files (dotfiles) are ignored, so you can store fixtures right next to your tests. Run urchin from inside the tests directory.

Urchin only cares about the exit status, so you can actually write your tests in any language, not just shell.

More about writing tests

Tests are organized recursively in directories, where the names of the files and directories have special meanings.

tests/
  setup
  setup_dir
  bar/
    setup
    test_that_something_works
    teardown
  baz/
    jack-in-the-box/
      setup
      test_that_something_works
      teardown
    cat-in-the-box/
      fixtures/
        thingy.pdf
      test_thingy
  teardown

Directories are processed in a depth-first order. When a particular directory is processed, setup_dir is sourced before everything else in the directory, including subdirectories. teardown_dir is sourced after everything else in the directory.

A directory's setup file, if it exists, is sourced right before each test file within the particular directory is run, and the teardown file is sourced right after.

Files are only run if they are executable, and files beginning with . are ignored. Thus, fixtures and libraries can be included sloppily within the test directory tree. The test passes if the file exits 0; otherwise, it fails.

urchin looks for files within a directory in the following manner,

for file in *; do
  do_something_with_test_file $file
done

so files are run in whatever order * produces. The order is configured in your environment, at least in GNU systems. Other systems may ignore the locales configured in the environment and always produce ASCIIbetical order.

Results are always printed in ASCIIbetical order, regardless of what order the tests ran in.

Below you can see how the locale can affect the order.

$ printf '!c\n@a\n~b\n' | LC_COLLATE=C sort
!c
@a
~b
$ printf '!c\n@a\n~b\n' | LC_COLLATE=en_US.UTF-8 sort
@a
~b
!c
$ printf '!c\n@a\n~b\n' | sort -d
@a
~b
!c

Writing cross-shell compatibility tests for testing shell code

While you could write your test scripts to explicitly invoke the functionality to test with various shells, Urchin facilitates a more flexible approach.

The specific approach depends on your test scenario:

  • (a) Your test scripts invoke scripts containing portable shell code.
  • (b) Your scripts source scripts containing portable shell code.

(a) Cross-shell tests with test scripts that invoke shell scripts

Urchin sets the TEST_SHELL environment variable so that you may change the shell with which your tests call other shell programs. To run your test scripts in multiple shells you must call $TEST_SHELL in your tests and then run urchin with the appropriate option.

In your test scripts, invoke the shell scripts to test via the shell specified in environment variable TEST_SHELL rather than directly; e.g.: $TEST_SHELL ../foo bar (rather than just ../foo bar).

Urchin runs tests in multiple different shells by default; Urchin has a list of default shells, and the following command will run your tests in all of those shells that Urchin detects.

./urchin ./tests

You can override the default list of shells with the -s flag.

urchin -s sh -s ksh ./tests

You can also

If TEST_SHELL has no value, Urchin defines it as /bin/sh, so the test scripts can rely on $TEST_SHELL always containing a value when Urchin runs them.

That said, we still recommand that you account for the possibility that $TEST_SHELL does not contain a value so that you may run your test scripts without Urchin. Supporting this case is very simple; when you invoke scripts that happen to be in the current directory, be sure to use the prefix ./, e.g., $TEST_SHELL ./baz rather than $TEST_SHELL baz.

(b) Cross-shell tests with test scripts that source shell scripts

If you source shell code in your test scripts, it is the test scripts themselves that must be run with the shell specified.

Urchin supports the -s <shell> option, which instructs Urchin to invoke the test scripts with the specified shell; e.g., -s bash.
(In addition, Urchin sets environment variable TEST_SHELL to the specified shell.)

Note that only test scripts that either have no shebang line at all or have shebang line #!/bin/sh are invoked with the specified shell. This allows non-shell test scripts or test scripts for other languages or for specific shells to coexist with those whose invocation should be controlled by -s.

References

On shell programming

More Repositories

1

openprism

Type your search in one search bar, and get results from all of the Socrata and CKAN portals.
JavaScript
39
star
2

nyc-crime-map

Python
22
star
3

data-wranglers-dc-pdfs

19
star
4

www.thomaslevine.com

Thomas Levine's old homepage
JavaScript
13
star
5

socrata-download

Shell
10
star
6

socrata-pricing

10
star
7

aaron-swartz

Python
8
star
8

socrata-analysis

JavaScript
7
star
9

scott

JavaScript
6
star
10

scott-documents

Wetland permit application documents
6
star
11

vlermv

Python
6
star
12

pickle-warehouse

Python
5
star
13

craigsgenerator

Python
5
star
14

special_snowflake

OpenEdge ABL
5
star
15

openlawsf

5
star
16

krounq

R
5
star
17

feedformatter

feedformatter is a Python library for generating news feeds in RSS and Atom formats.
Python
4
star
18

friendly_brief

Python
4
star
19

open-data-500

R
4
star
20

lazydriver

Scrape with a Chrome extension and push to a couch
JavaScript
4
star
21

ckan-datasets

3
star
22

nyc-crime-map-data

3
star
23

dadaportal

Python
3
star
24

picklecache

Python
3
star
25

pluplusch

Python
3
star
26

horetu

Python
2
star
27

highwall-fixtures

Fixtures for Highwall tests
2
star
28

plan-things

Shell
2
star
29

nps_weather

HTML
2
star
30

dicti

Case-insensitive dictionary
Python
2
star
31

data-guacamole

Python
2
star
32

barelywebgit

2
star
33

whom-to-email

R
2
star
34

cured-foods

Python
2
star
35

risley-floor-plans

2
star
36

wsync

2
star
37

ggplot-not-r

R
2
star
38

fizzbuzz-latex

2
star
39

arabic-tweets

R
2
star
40

hssas

Haskell
2
star
41

parsing-pdfs-workshop

Python
2
star
42

nyc-data-downloads

Downloads of the NYC data bank
2
star
43

socrata-defederate

2
star
44

n.an

Noncomprehensive Dotfile Archive Network
Shell
2
star
45

how-to-scrape

How to scrape websites
Python
2
star
46

datakind-scy

2
star
47

open-data

R
2
star
48

delaware

Python
2
star
49

treegit

Off-the-self cgit server with some helpers
Shell
2
star
50

couch.thomaslevine.com

Tom's CouchDB server
1
star
51

status.thomaslevine.com

1
star
52

whitbygroup

JavaScript
1
star
53

openlawoakland

Python
1
star
54

geom_doner

R
1
star
55

dumptruck-website

Website for dumptruck
JavaScript
1
star
56

hipstogram

Pretty sure the hipstogram is a better visualization tool than the histogram.
R
1
star
57

socrata-nominate

JavaScript
1
star
58

intherooms-meetings-sf

1
star
59

nypd-xy

R
1
star
60

nfsn-helpers

PHP
1
star
61

bashful-fs

1
star
62

audio-cable-power-controller

1
star
63

meetup-users-meetup

http://www.meetup.com/MeetupUsers/
1
star
64

dep

1
star
65

course-map

1
star
66

formaldehyde

1
star
67

spreadsheet-corpus

1
star
68

closeddada

Python
1
star
69

united-states-middlenames

Python
1
star
70

gkebd

Python
1
star
71

csv-soundsystem

1
star
72

unwatermark

Python
1
star
73

code-against-america

1
star
74

Deleware-Corporations-Scraper

Python
1
star
75

smart_csv_dictreader

Python
1
star
76

bucket-wheel

Bucket-Wheel Excavator
Python
1
star
77

SocialValue

Python
1
star
78

python-daemon-example

Python
1
star
79

htmltable2matrix

Convert an html table to a list of lists in Python
Python
1
star
80

immaterialdigitallabor.net

HTML
1
star
81

github-user-growth

1
star
82

intherooms-meetings-ny

1
star
83

geom_taco

R
1
star
84

chainsaw.thomaslevine.com

1
star
85

scraperwiki-kpi

ScraperWiki key performance indicators
R
1
star
86

chainsaw

Web scraping tools
1
star
87

conveyor-belt

Distributed file-based email archival system
1
star
88

scraperwiki-exp14

1
star
89

ouekque

Haskell
1
star
90

postsecret-downloads

1
star
91

rifidec

Scraping http://www.rifidec.org/membres/infomembres.htm
1
star
92

gastronomification-big-data-talk

HTML
1
star
93

git.thomaslevine.com-fail1

PHP
1
star
94

hyde-h5bp

Hyde starter structure with HTML5Boilerplate post-processing
JavaScript
1
star
95

dieselfuel

Helpers for web scrapers
1
star
96

dwb-neef

1
star
97

euler

Haskell
1
star
98

script_kiddie_bot_confuser

Confuse bots that are trying to get into your site
Python
1
star
99

acpr-banque-de-france

Python
1
star
100

201204-homepage-experiment

R
1
star