Pg tap

345 views
237 views

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
345
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Pg tap

  1. 1. Pgtap Unit testing for Postgresql Lucio Grenzi l.grenzi@gmail.com PGDay.IT 2013 – 25 Ottobre 2013 - Prato 1 di 24
  2. 2. Who I am Delphi developer since 1999 IT Consultant Front end web developer Postgresql addicted Nonantolando.blogspot.com lucio.grenzi lucio grenzi PGDay.IT 2013 – 25 Ottobre 2013 - Prato 2 di 24
  3. 3. Agenda PgTap: introduction Why use this tool Best practices Q&A PGDay.IT 2013 – 25 Ottobre 2013 - Prato 3 di 24
  4. 4. Question before starting Why would you want to unit test your database? PGDay.IT 2013 – 25 Ottobre 2013 - Prato 4 di 24
  5. 5. Why use pgTap Backend application development Test schema object validation Module development Continuos integration PGDay.IT 2013 – 25 Ottobre 2013 - Prato 5 di 24
  6. 6. Tap protocol The Test Anything Protocol (TAP) is a protocol to allow communication between unit tests and a test harness. It allows individual tests (TAP producers) to communicate test results to the testing harness in a language-agnostic way. Originally developed for unit testing of the Perl interpreter in 1987, producers and parsers are now available for many development platforms. -wikipedia- PGDay.IT 2013 – 25 Ottobre 2013 - Prato 6 di 24
  7. 7. PgTap pgTAP is a unit testing framework for PostgreSQL written in PL/pgSQL and PL/SQL. It includes a comprehensive collection of TAP-emitting assertion functions, as well as the ability to integrate with other TAP-emitting test frameworks. It can also be used in the xUnit testing style. -http://pgtap.org/- PGDay.IT 2013 – 25 Ottobre 2013 - Prato 7 di 24
  8. 8. PgTap now www.pgtap.org Latest version is 0.93.0 Already packaged for the most important linux distributions make make installcheck make install PGDay.IT 2013 – 25 Ottobre 2013 - Prato 8 di 24
  9. 9. Requirements PostgreSQL 8.1 or higher with 8.4 or higher recommended for full use of its API PL/pgSQL On Windows servers is necessary to install Perl Perl on Linux is no more necessary but it is required by pg_prove PGDay.IT 2013 – 25 Ottobre 2013 - Prato 9 di 24
  10. 10. Adding PgTap to a database Install pgtap in a database psql -d dbname -f pgtap.sql include the call to pgtap.sql in your script with /pgtap.sql i remove pgtap from a database psql -d dbname -f uninstall_pgtap.sql PGDay.IT 2013 – 25 Ottobre 2013 - Prato 10 di 24
  11. 11. Tap in practice Test output is easy to understand BEGIN; SELECT plan(); ---- how many test? …put your tests here… SELECT * FROM finish(); ---- test finished, print report ROLLBACK; PGDay.IT 2013 – 25 Ottobre 2013 - Prato 11 di 24
  12. 12. PgTap functions - compare ok() is() isnt() matches() doesnt_match() alike() unalike() cmp_ok() pass() fail() SELECT ok( :boolean, :description ); SELECT is ( :have, :want, :description); SELECT isnt(:have, :want, :description); SELECT matches( :have, :regex, :description ); SELECT doesnt_match( :have, :regex, :description ); SELECT alike( :this, :like, :description ); SELECT unalike( :this, :like, :description ); SELECT cmp_ok( :have, :op, :want, :description ); SELECT pass( :description ); SELECT fail( :description ); PGDay.IT 2013 – 25 Ottobre 2013 - Prato 12 di 24
  13. 13. PgTap functions – test failures throws_ok() throws_like() throws_matching() lives_ok() performs_ok() SELECT throws_ok( :sql, :errcode, :ermsg, :description ); PGDay.IT 2013 – 25 Ottobre 2013 - Prato 13 di 24
  14. 14. PgTap functions – test objects tablespaces_are() schemas_are() tables_are() views_are() sequences_are() columns_are() indexes_are() triggers_are() functions_are() roles_are() users_are() groups_are() languages_are() opclasses_are() rules_are() types_are() domains_are() enums_are() casts_are() operators_are() PGDay.IT 2013 – 25 Ottobre 2013 - Prato 14 di 24
  15. 15. PgTap basics set ON_ERROR_ROLLBACK 11 set ON_ERROR_ROLLBACK set ON_ERROR_STOP true set ON_ERROR_STOP true set QUIET 11 set QUIET BEGIN; BEGIN; SELECT plan(1); SELECT plan(1); SELECT pass( 'Hello PgDayit !'!'); SELECT pass( 'Hello PgDayit ); SELECT **FROM finish(); SELECT FROM finish(); ROLLBACK; ROLLBACK; save this as HelloPgDayit.txt and type: psql -U postgres -f HelloPgDayit.txt 1..1 1..1 ok 11- -Hello PgDayit ! ! ok Hello PgDayit PGDay.IT 2013 – 25 Ottobre 2013 - Prato 15 di 24
  16. 16. Let's create some tables BEGIN; i ./pgtap.sql -- create two tables with referential constraint create table table1 (id integer not null, t_text varchar(100), dt timestamp default now(), CONSTRAINT table1_pkey PRIMARY KEY (id)); create table table2 (id integer not null, t_text varchar(100), id_ref integer, CONSTRAINT id_ref FOREIGN KEY (id_ref) REFERENCES table1 (id)); insert into table1 (id,t_text) values (1,'test one'); insert into table1 (id,t_text) values (2,'test two'); insert into table1 (id,t_text) values (3,'test three'); insert into table2 (id,t_text,id_ref) values (1,'ref test one', 1); insert into table2 (id,t_text,id_ref) values (2,'ref test two', 2); insert into table2 (id,t_text,id_ref) values (3,'ref test three', 3); SELECT plan(6); ## type tests here## ## get results here## SELECT * FROM finish(); ROLLBACK; PGDay.IT 2013 – 25 Ottobre 2013 - Prato 16 di 24
  17. 17. Test samples PREPARE ids_fetched AS PREPARE ids_fetched AS select id from table1 where id in (1,2,3) order by id asc; select id from table1 where id in (1,2,3) order by id asc; PREPARE ids_expected AS VALUES (1),(2),(3); PREPARE ids_expected AS VALUES (1),(2),(3); SELECT results_eq( 'ids_fetched', 'ids_expected', SELECT results_eq( 'ids_fetched', 'ids_expected', 'fetched the expected ids from table1'); 'fetched the expected ids from table1'); PREPARE ids_fetched1 AS select id PREPARE ids_fetched1 AS select id from table1 where id in (1,2,3) order by id asc; from table1 where id in (1,2,3) order by id asc; PREPARE ids_fetched2 AS select id PREPARE ids_fetched2 AS select id from table2 where id in (1,2,3) order by id asc; from table2 where id in (1,2,3) order by id asc; SELECT results_eq( 'ids_fetched1', 'ids_fetched2'); SELECT results_eq( 'ids_fetched1', 'ids_fetched2'); PREPARE throw_error AS PREPARE throw_error AS insert into table1 (id,t_text) insert into table1 (id,t_text) values (1,'duplicate key error'); values (1,'duplicate key error'); SELECT throws_ok('throw_error','23505',NULL, SELECT throws_ok('throw_error','23505',NULL, 'duplicated key found (id)'); 'duplicated key found (id)'); PGDay.IT 2013 – 25 Ottobre 2013 - Prato 17 di 24
  18. 18. pg_prove command-line application to run one or more pgTAP tests in a PostgreSQL database output of the tests is processed by TAP::Harness in order to summarize the results Tests can be written as: SQL scripts xUnit-style database functions PGDay.IT 2013 – 25 Ottobre 2013 - Prato 18 di 24
  19. 19. pg_prove output % pg_prove ­U postgres tests/ % pg_prove ­U postgres tests/ tests/coltap.....ok tests/coltap.....ok tests/hastap.....ok tests/hastap.....ok tests/moretap....ok tests/moretap....ok tests/pg73.......ok tests/pg73.......ok tests/pktap......ok tests/pktap......ok All tests successful. All tests successful. Files=5, Tests=100,  1 wallclock secs  Files=5, Tests=100,  1 wallclock secs  ( 0.06 usr  0.02 sys +  0.08 cusr  0.07 csys =  0.23 CPU) ( 0.06 usr  0.02 sys +  0.08 cusr  0.07 csys =  0.23 CPU) Result: PASS Result: PASS PGDay.IT 2013 – 25 Ottobre 2013 - Prato 19 di 24
  20. 20. pg_prove - xUnit Test Functions EATE OR REPLACE FUNCTION setup_insert( REATE OR REPLACE FUNCTION setup_insert( RETURNS SETOF TEXT AS $$  RETURNS SETOF TEXT AS $$   RETURN NEXT is( MAX(lucio), NULL, 'Should have no users') FROM speakers;    RETURN NEXT is( MAX(lucio), NULL, 'Should have no users') FROM speakers;   INSERT INTO speakers (lucio) VALUES ('theory');    INSERT INTO speakers (lucio) VALUES ('theory');  LANGUAGE plpgsql; $ LANGUAGE plpgsql; eate OR REPLACE FUNCTION test_user( reate OR REPLACE FUNCTION test_user( RETURNS SETOF TEXT AS $$  RETURNS SETOF TEXT AS $$   SELECT is( lucio, 'theory', 'Should have nick') FROM speakers;    SELECT is( lucio, 'theory', 'Should have nick') FROM speakers; D; ND;  LANGUAGE sql; $ LANGUAGE sql; % pg_prove ­­dbname pgdayit ­­runtests % pg_prove ­­dbname pgdayit ­­runtests runtests()....ok runtests()....ok All tests successful. All tests successful. Files=1, Tests=16,  0 wallclock secs  Files=1, Tests=16,  0 wallclock secs  ( 0.02 usr  0.01 sys +  0.01 cusr  0.00 csys =  0.04 CPU) ( 0.02 usr  0.01 sys +  0.01 cusr  0.00 csys =  0.04 CPU) Result: PASS Result: PASS PGDay.IT 2013 – 25 Ottobre 2013 - Prato 20 di 24
  21. 21. Conclusions There are functions for almost everything in your postgresql db Triggers, Functions, Schemas, Tablespaces, …. It is possible create relationships of, or better conditional, tests Stable PGDay.IT 2013 – 25 Ottobre 2013 - Prato 21 di 24
  22. 22. Risorse Citare tutte le risorse utili: www.pgtap.org https://github.com/theory/pgtap PGDay.IT 2013 – 25 Ottobre 2013 - Prato 22 di 24
  23. 23. Questions PGDay.IT 2013 – 25 Ottobre 2013 - Prato 23 di 24
  24. 24. PGDay.IT 2013 – 25 Ottobre 2013 - Prato 24 di 24

×