Apologies for top posting and I'll give this post the attention it deserves later (by all means track me down Jens if I forget) but one thing struck me immediately and that was sections in DBD pod like DBD::ODBC's deviations from the DBI specification at http://search.cpan.org/~mjevans/DBD-ODBC-1.43/ODBC.pm#Deviations_from_the_DBI_specification

Some of these might be really difficult to deal with in test code. Over the years I've submitted many patches to tighten the DBI specification but at the end of the day having maintained a DBD for quite a while deviations from the specification are just reality. Trying to make all DBDs the same is a really difficult task which DBI does well for the most part but I keep coming up with new cases - just search in dbi-dev for threads containing "clarification" from me. In particular see last_insert_id which DBD::ODBC has almost no chance of supporting.

As an aside the err, native and errstr are still a continual problem for some of the work I do in that there is only one per DBI and they are not per stmt - contrary to ODBC where the native error and error string is per stmt, dbc or env. Yes, I could have done something about this but it always seemed harder to address than it first seemed since it is engrained in DBI since day one. Or my memory could be worse than I think and Tim will correct me.


Martin

On 01/07/2013 22:55, Tim Bunce wrote:
On Mon, Jul 01, 2013 at 04:45:37PM +0200, Jens Rehsack wrote:
Hi all,

I decided it's best to discuss it in public than in a github repository.
We can easier answer / quote / split discussions than in a push/pull battle.

# DESIGN

Currently this is a list of open issues and discussion points...

Topics can be removed once they're settled and the relevant docs have been
updated.


## DBI::Test as a DBD author's tool

This is the principle use-case for DBI::Test: to provide a common suite of
tests for multiple drivers.

Currently documented as

--- BEGIN
This module aims at a transparent test suite for the DBI API
to be used from both sides of the API (DBI and DBD) to check
if the provided functionality is working and complete.
--- END

Does it satisfy that point?

The phrase "used from both sides of the API" seems unclear to me.
Perhaps use this simpler wording:

     This module aims to be a test suite for the DBI API and
     an underlying DBD driver, to check
     if the provided functionality is working and complete.


We need to consider how evolution of DBI::Test will affect driver authors.
Specifically, as DBI::Test add new tests it's quite likely that some drivers
will fail that test, but that failure is not a regression for the driver.

Well - from my point of view, it is. A lot of drivers (including those
coming with DBI) doesn't conformDBI API in a lot of cases. Step by
step (finally Tux) discovers them by enhancing DBD::CSV tests.

Sure, but that's not a "regression" in the technical sense of being
"previously working but now broken". It's just uncovered an old bug.

So it seems reasonable for DBI::Test to be primarily a developer tool
and not run as a standard part of the drivers' test suite, at least for now.
In other words, DBI::Test would only be run if AUTHOR_TESTING is true.

That's not designed for being an AUTHOR_TESTING tool. It's designed for
exactly the opposite - to allow authors detecting issues in a very wide
range of situations.

I see this as a period of transition. AUTHOR_TESTING first, then
AUTOMATED_TESTING (cpantesters), then a full dependency.

The rate of progress through those steps should be up to the
individual driver authors. In fact it simply has to be.

So DBI::Test should aim to make progress through those steps
as smooth and rewarding as possible. Low cost, high benefit.
Otherwise driver authors are less likely to make the effort.


Choose DBD::DBM as first example: [...]
Second example: DBD::ODBC [...]
On design goal of DBI::Test is to manage those differences [...]

Of course, that's all very good and I agree.

Consider a Random User runing "cpanm DBD::Foo" to install DBD::Foo.
My point is ONLY that that user shouldn't get a failure simply because a
new DBI::Test release has a new test that causes DBD::Foo to fail
because of an old bug.


That also allows us to duck the issue of whether DBD's should list DBI::Test as
a dependency. At least for now.

DBI lists DBI::Test as dependency. That's why we're having a lot of
fun when doing common stuff in a way not introducing unnecessary
dependencies (read: almost none except core).

I don't see DBI::Test listed in Makefile.PL.


## DBI::Test as a DBI developer's tool

The goal here would be to test the methods the DBI implements itself and the
services the DBI provides to drivers, and also to test the various drivers
shipped with the DBI.

This is a secondary goal, but is important because DBI::Test will probably
become the primary test suite for the drivrs that ship with DBI.

If I understood those sentences correctly, this is the primary goal.

I see sharing a common test suite among multiple drivers as the primary
goal. Becoming a test suite for the DBI itself is a very useful
side-effect.

But we're probably "splitting hairs" - there's not much value in
debating primary vs secondary goals as they're both important :)


## Define what DBI::Test is NOT trying to do

* It's not trying to test the database SQL behaviour (ORDER BY, JOINs etc).
Databases (an drivers that implement their own databases) should have their
own test suite for that.

Yes and no. It doesn't provide tests for that by default. But it would
allow to create a CPAN distribution DBI::Test::ANSI_SQL and deploy test
cases for that.

Anyone who has installed those module might have additional tests when
running "make test". This is wanted.

I can see value in a generic extension mechanism.


* It's not trying to test the database SQL syntax. As many tests as possible
should be usable even for databases that don't use SQL at all.

Ehm …
AFAIK we decided that otherwise. But it should be easy (or at least,
could be easily made possible) to improve the match-check to catch
only SQL based drivers for SQL tests.

This is a job for the match => sub :)

I suspect that's going to be limited, but I'm happy to be proved wrong.


## List some minimum and other edge cases we want to handle

Example: Using the DBM with SQL::Nano parser.

This means that, as far as possible, all tests should use very simple
SQL and only one or two string columns.

Nano can do as much as columns you want, but yes.

Sure, but a basic key-value store won't, eg DBD::DBM without MLDBM.

The goal is, that SQL::Statement provides own DBI::Test plugins.
And a configuration plugin for DBI::Test catching any DBI::DBD::SqlEngine
based DBD's and create additional test setups for them.

Read: When DBI is installed after SQL::Statement, DBI's test suite
is enhanced by the SQL::Statement tests for DBI::DBD::SqlEngine, DBD::File
and DBD::DBM - if SQL::Statement becomes installed after DBI, it's
vice versa.

Okay.

My point is simply that a very large proportion of the DBI and DBD API
and behaviour can be tested with statements that involve only two columns.
So all tests that can be written with two columns should be.



## Should we create .t files at all, and if so, how many?

There's a need to have a separate process for some test cases, like
testing DBI vs DBI::PurePerl. But others, like Gofer (DBI_AUTOPROXY)
don't need a separate process.

The question for so many ".t" files doesn't came from the requirement
of own processes. It came from several perspectives:

1) make it easier to debug a single test fail
    (ever tried to figure out what really failed in
     SQL-Statement/t/06virtual.t when all possible test variant
     could be run? There're over 1500 tests in one file …)
2) make it possible to run as much as possible parallel
    (yes, we expect 18+ Core per chip on Haswell Xeon's and
     up to 8 processor sockets per machine …)

*nods*

Let's keep the generation of test files for now, but keep in mind the
possibility that some 'context combinations' might be handled
dynamically in future, i.e., inside the run_test() subroutine.

Maybe or maybe not. You probably can't decide on generation
if a setting can be clearly undone (like DBI_AUTOPROXY) or not
(like DBI_SQL_NANO).

Maybe we can improve DBI::DBD::SqlEngine at a point in future to
have the same flexibility there (stealing the RootClass technology
from DBI ^^).

Anyway - this can be very tricky and have interesting side effects
producing a lot of false positives which nobody wants.

*nods*


## How and where should database connections be made?

I think the modules that implement tests should not perform connections.
The $dbh to use should be provided as an argument.

This is a must-have. Because we want to generate several test
variants for DBD::DBM with several backends (as well as for
DBD::CSV).

I'm not sure if you're agreeing with me.

[...some specific implementation details...]

Feature request :P
Nice one, but later - let's go out before YAPC::EU!
And it's voluntary work … :D

Sure. And I'm happy to help.  At the moment, though, I don't know if my
implementing some of the items above would cause more pain than gain.

I just want to be sure we're all helping in roughly the same direction :)

Tim.



--
Martin J. Evans
Wetherby, UK

Reply via email to