Codeception / module-db

DB module for Codeception

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[RFC] grabEntryFromDatabase

igorsantos07 opened this issue · comments

While testing a REST API I found myself needing an entire entry from the database to make sure my GET /table/«id» was implemented correctly.
However, I just found a method to retrieve a field from the database, not an entire entry.

As I'm not experienced with testing yet I would like to know some opinions about implementing a grabEntryFromDatabase method in the Db module, so we can use it to get pure information from the db and then use that to test what the system is doing.

Currently I'm using my own models to get the needed information, but this is the same the API is doing and the test is almost redundant...

Also, if there's any better practice on this, please let me know (:

Well, why would you need entry if you need just an id field?

noob says:
Not sure =(
Well, the ID is what I sent in the request, so testing only it would be enough, and I would just trust the request is sending me good data?
A good reason for testing the entire request (or at least a couple of fields) would be if I have some business rules being applied to the fields and stuff, then?

if you really want to test response content, than it is better to hardcode expected field names and check their existence in the response

Hmmm yeah, that makes sense. I just wanted to not repeat the test data
between the database dump and my bootstrap file.
On Jun 4, 2013 2:38 PM, "tiger-seo" notifications@github.com wrote:

if you really want to test response content, than it is better to hardcode
expected field names and check their existence in the response


Reply to this email directly or view it on GitHubhttps://github.com/Codeception/Codeception/issues/347#issuecomment-18925868
.

So, does this issue still has a sense ?

Not sure. I'm already using hard coded test data, but I still feel
uncomfortable by having repeated stuff in my tests, i.e. between the db
dump and the bootstrap file.
Do you think it could make sense to avoid this, DRYing the tests with a way
to retrieve info from the database?
On Jun 11, 2013 8:21 PM, "tiger-seo" notifications@github.com wrote:

So, does this still has a sens ?


Reply to this email directly or view it on GitHubhttps://github.com/Codeception/Codeception/issues/347#issuecomment-19298771
.

Ok, so you want grabEntryFromDatabase to use the id to take a record from database?
Not sure this is really needed as we have grabFromDatabase.

Yes, maybe its better to take all the columns at once, but I think, to make test more readable you should explicitly specify which data from database you use.

commented

I really think this should be implemented. I cannot believe that this is not requested feature.
I'm testing the registration process in my app and immediately this jumped to me as missing functionality from testing FW.

I do need to fetch full row from database and there is not a elegant solution to do that in Codeception.
Will you look into that by yourself? Are you open into implementing this? Do you need help with this (maybe you don't have time, but accept PR)?

@srigi Could you show the relevant bits of your test to demonstrate why you need a full row?

commented

No problem. This is the DB schema I have:

schema

During registration I setup auth_token for user identified by email. status, type, token and link are essential in email verification process. Of course I cannot/don't-want to access verification email sent from server.
So I go to DB to see if all assets are set correctly after submitting email address in 1st step of registration.

$I->fillField(Registration::$emailField, $testUserEmail);
$I->click(Registration::$submitButton);
$I->seeInDatabase('user', [
    'email' => $testUserEmail,
]);
$userUuid = $I->grabFromDatabase('user', 'uuid', [
    'email' => $testUserEmail,
]);
$I->seeInDatabase('auth_token', [
    'user_uuid' => $userUuid,
    'type' => 'registration',
    'status' => 'pending',
]);
$authTokenLink = $I->grabFromDatabase('auth_token', 'link', [
    'user_uuid' => $userUuid,
]);
$I->seeCurrentUrlEquals(Registration::route("/email-info/$authTokenLink"));
$I->see('Please finish your registration by clicking the link in email we sent to');
$I->see($testUserEmail);

$authTokenToken = $I->grabFromDatabase('auth_token', 'token', [
    'user_uuid' => $userUuid,
]);
$I->amOnPage(Registration::route("/activate/$authTokenToken"));
$I->see('Terms of use');
$I->see('I agree with terms of use');
$I->see('Continue');

You can see I need link and token from auth_token in this single test. Grabbing whole row (or named columns) would be appreciated.

I need this feature as well. I am testing large data importing from ini like formatted files. So I must be sure that some variables reach to tableA and other variables to tableB as whole records. So checking field by field is only a waste of bandwidth in this situation. Even changing "param string $column" to "param array $columns" in grabFromDatabase() will help significantly.

I also use grabSetFromDatabase() and addOrderClause() function which I wrote to retrieve ordered datasets from database to check consequential entries are imported successfully and all are reachable via frontend in database order.

I would like this feature as well. And it doesn't seem to be very difficult to add, am I right?

Maybe proceedSeeInDatabase($table, $column, $criteria) could have a mixed $column parameter:

  • If it is a string, it will return a single column.
  • If it is an array it will return the columns from the array.
  • We could at string "*" as a shortcut to retrieve all columns.

If it helps I could look into this and make a PR. I've never done that before so I could use a good reviewer :)

9 years later, this basic functionality is still not implemented...
@eXorus would you at least accept a PR implementing this feature ?

You are welcome to raise pull request.

Doctrine2 module got a similar feature in 2017: Codeception/Codeception#4030

Agree, you can do the PR, it's a feature I gonna use.

For now I'm using executeInDatabase to get multiples columns.

So we will have

$I->grabFromDatabase('users', 'email', ['id' => 123]);
// to get the email from the users table

$I->grabFromDatabase('users', ['email', 'name'], ['id' => 123]);
// to get the email and name from the users table

or with another method.

@eXorus as you can see in #43 , the API is :

$I->grabEntryFromDatabase('users', ['id' => 123])

I was hesitant to add a set of columns as parameter and I decided to go for brevity because it's a test so the bandwidth and the broad performance isn't relevant.

Implemented by #43