-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixtures initializer #1956
Comments
Will work on this one and make PR :) |
And as a reminder for myself: add two events before/after fixtures load. |
well after some thinking, i guess i need core developers opinions here. @cebe @samdark @qiangxue whats your thoughts on this one? |
I'm for implementing it. |
Do we really need this? Note that each fixture is a PHP file. You can put code there to do initialization work. For global initialization work, do it in |
currently it is so, for table fixtures, they are simple plain php-files, and end-user may need (i am sure about this) to customize some database env. setup.
yes, but we are not talking about global initialization about partial, see point 3 in the list. |
What is the difference between using plain php-file and |
how will you do this with plain php-fixtures files? Example can be like in yii2-advanced, need to tests Users model, it hits database. But you dont need to load all dump, just one small piece. how will you do this? also take into account that fixtures files will be generated automatically by faker so you cant write in them something like
not a big one to be true. There also will be |
Alright, I'm convinced. Thanks for explaining. Now I have some questions about the initializer design.
And also a wild thought: How about we introducing
|
only one.
very similar to getModels/getRows. We only need to check if the file with fixtureName+initializerSuffix exists and simply create it. Then run it method
i think thats a great idea, some workaround and features can be added in this area.
yes, cool, but we already have
need more talks and suggestions here. I think after basic implementation of initializer we will return to this.
yep, after implementing initializers we will have more or less understanding where to move on.
well, we have Also keep in mind that we have this ticket - #1521 that also will give us good abilities for database clean-up and clean-up strategies. You can see same-named ruby gem for more info. |
where is it? My idea was actually redesigning the whole fixture stuff.
|
currently in my mind)) because code is not written yet. well i like all your suggestions but i dont think that currently we will have time on them. for now we need to introduce to the developers some useful tools. After we have something working we can make some redesigning and other to see if it will work or not, but we already will have some fallback implemented. |
And we also should not end up with something big and over-abstracted-layered like |
@qiangxue also would be interesting to know your opinion on https://github.com/cakephp/cakephp/tree/master/lib/Cake/Test/Fixture as i see you are thinking of something looks a like. |
Thanks for the pointer. Will look into it. |
hm, good to know that you are working on it, but as an end-user i would like to point that it should be very easy to setup and use. Because end-user dont want to manage all this deps and configs he only want it work asap, it was one of the main reasons why i like Yii1 fixtures - very simple to write, very simple to use and understand. P.S. can you also assign this issue to yourself then? |
Sure. I also want to keep simplicity. Below is a use example (not finalized yet). Your suggestions are welcome. class UserFixture extends DbFixture
{
public $modelClass = 'app\models\User';
public function loadData()
{
return [...]; // or require external data file
}
}
class MyTestCase
{
protected function setUp()
{
$this->getFixtureManager()->load([
UserFixture::className(),
]);
}
protected function tearDown()
{
$this->getFixtureManager()->unload();
}
public function testSave()
{
$user1 = UserFixture::getModel('user1');
$rows = UserFixture::getRows();
}
} |
hm, i like it, but i think that in fixture class Also is there some code about how it will load plain-php files? I think that after you will end up your work we can add/adjust And i think that Fixture should implemnt __get() and __set() as in Yii1 DbTestCase where |
Yes, adding |
i guess they can be taken in
true, thats why i was considering to invite here @cebe and @klimov-paul , but looks like they are busy enough now. I will also need their help in this issue. |
If an application needs two different DBs (one mysql, the other sqlite or redis), what kind of fixture manager should we use? one manager or two? |
i guess that public $fixtures = [
'tbl_user' => [
'db' => 'some_my_connection'
],
]; since fixtures are objects now. But need to deal with aliasing i guess, like in current |
Well, my plan is that |
hm, but the third approach is just about, no? |
What's the third approach? |
public $fixtures = [
'tbl_user' => [
'db' => 'some_my_connection'
],
];
or i misunderstand something?) |
|
so, whats the problem then?) if we can explicitly set public $fixtures = [
'tbl_user' => [
'db' => 'mongo_node_2'
],
];
well, i think that if |
What does fixture manager do? What about disabling/enabling integrity checks? what about loading global init scripts? |
Yes, I'm questioning the need of |
Nope, |
p1. This is just a schema fixture. If your test needs it, declare it in The new fixture design makes a lot of sense because: it generalizes the fixture concept, not just dealing with DB fixtures; it unifies fixture references (how to refer to a fixture); it allows you to organize fixtures better with the dependency concept. Yii1 FixtureManager doesn't handle any of these. Is it more complex than Yii1 FixtureManager? Absolute not. For example, you can put the fixture data directly within a fixture class rather than in a different file. The result will be that you have the same number of fixture files as in Yii1 but with greater control and flexibility. |
only talks, no real profit :)
yes :) its not complex for you because you developed it.
i dont want to create another fixture just for schema. It should be in fixture class of the
currently i cant, and i dont want to use it in test, because see above. @qiangxue i was using fixtures/db-test-case in Yii1 (such a pain) and this features is really needed, i dont get why you still |
If this is your attitude, I will not argue anymore since I have already given docs and examples.
You want to put it in an initializer class, but not a fixture class. What an argument?
True, but that's something to be fixed.
Because you never answered me. See: #1956 (comment) |
i answerd you that schema is part of fixture, in this way its more easy to handle testing.
argument is p1,2 in issue description. So overall what is your suggestion? how to handle schema-creating in custom ways? creating +1 schema-fixture for each fixture? bad idea. |
Why do you need a schema fixture for each fixture? Why do you want to repeat what you have done in DB migrations? For example, I want to add a column to the user table. Does this mean I need to add a new DB migration as well as modify the initializer with nearly identical code? |
because i dont want to make copy-paste of init-schema things (creating tables, fk, etc) each time in different tests where fixture is used.
why are we still talking about migrations? what is the use case of migrations here? no use-case.
yes, thats why you write your tests not once and forget about it, but also crafting them and working on them during the development time. But once again migrations have nothing to deal with testing (only if we provide So overall whats your solution, how i should handle custom creating? Example: class UsersTest extends TestCase
{
protected function setUp()
{
Yii::$app->createCommand()->createTable('users', [...]);
}
} class UsersProfilesTest extends TestCase
{
protected function setUp()
{
Yii::$app->createCommand()->createTable('users', [...]);
Yii::$app->createCommand()->createTable('users_profiles', [...]);
}
} So as you see above in example its huge problem of copy-pasting, and it just growing with a big number of tests, so if changed one field in schema, i need to go through all this tests and just fix it rather then simply fixing 1 fixture file. I dont even talk here about some base principles of development as DRY, KISS as you see its all about it. |
Migration is used to adjust your DB schemes along the course of your development. Migrations can be applied to both production/development and test databases. Yes, when you make schema changes, you need to adjust fixture data as well - we're not writing test once and forget about it. But it seems to me pointless and error-prone if I have to modify in two places about the schema with the same change. This is even more problematic in a team development environment if because migration will coordinate simultaneous schema changes while in initializers, you have to manually deal with conflicts. |
I think I finally understand what you really want to do - you essentially want to represent a database schema in terms of multiple fixtures (plus an init schema) so that you save time when running tests, because you don't need to re-create the whole database each time. Correct? |
@qiangxue yep, exactly. I was playing with 12 tables (empty tables, just creating structure and dropping them + 2 tables fixtures data) and it took to run 2-3 seconds just 1 test in 1 test-case (simple |
What should be in the init schema? Or how to prepare the initial database? |
it is the developer choice, we just provide template method for this and thats it. Because he dont need to create all tables just to test 1 AR. |
I'm no longer questioning the necessity of your proposal. I'm convinced. |
you already have it: |
Should we also add a |
Ok, updated code/doc based on the above discussions: Code: master...feature-fixture |
no, it is user choice to decide what he want to reset what he want, in particular we cant guess execatly what is he thinking about in this way. I think Also good that dep. of So overall it looks fine to me, maybe after some playaround will get some issues/enh. but now its ok. Also could you then submit fix for |
Should this docs be fixed, or i misread something?
|
I still kept Perhaps you can help with the change needed for |
Ok.
Right, but i should start work after your PR merged. The only thing will be that i need to search fixture-initializer (fixture-class) by fixture name, and just set |
Already merged. Thank you for your critical reviews. It's very helpful. |
Hope, i was not rude)) Will work on |
Closing this one as implemented. |
Currently Yii2 support only one
init
plain file that will be included before fixtures load. This is good but not enough. For some different cases we may need special initializers per each fixture that will take care of creating triggers, views, maybe adding/deleting fk and other, so to avoid copy-paste betweensetUp
methods we need some class-initializer. For example:After initializer call fixture file will be loaded if it is exists. So ower goals after all:
setUp
of test-case, and we should avoid this copy-paste between different test-cases).The text was updated successfully, but these errors were encountered: