The "Testing The Rails" tutorial is now up-to-date covering the new functional test api in version 0.11+. [ To Read The Whole Thing ] http://manuals.rubyonrails.com/read/book/5 [ To Read The Chapter That Changed The Most] http://manuals.rubyonrails.com/read/chapter/28 Lemme know if there''s any issues. Steve
Steve Kellock wrote:> The "Testing The Rails" tutorial is now up-to-date covering the new > functional test api in version 0.11+. > > [ To Read The Whole Thing ] > http://manuals.rubyonrails.com/read/book/5 > > [ To Read The Chapter That Changed The Most] > http://manuals.rubyonrails.com/read/chapter/28 > > Lemme know if there''s any issues. > > SteveThanks Steve, this is excellent material. rgds Dema http://dema.ruby.com.br/
2005/5/19, Steve Kellock <skellock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> The "Testing The Rails" tutorial is now up-to-date covering the new > functional test api in version 0.11+. > > [ To Read The Whole Thing ] > http://manuals.rubyonrails.com/read/book/5 > > [ To Read The Chapter That Changed The Most] > http://manuals.rubyonrails.com/read/chapter/28 > > Lemme know if there''s any issues.Thanks a lot :) Two "bugs" I''ve found: 9.3 The 4 Hashes of the Apocolypse shouldn''t be "9.3 The 4 Hashes of the Apocalypse" ? and # this test proves that fetching a movie works def test_successfully_finding_a_movie get :movie, "id" => "1" assert_not_nil assigns["movie"] assert_equal 1, assigns["movie"].id assert flash.empty? end in the same paragraph... assert_equal 1, assigns["movie"].id fails for me cause it returns the id of the object not the id of the "movie" in the model. It works this way: assert_equal 1, assigns["movie"]["id"] HTH -- Lawrence http://www.oluyede.org/blog
On 19-mei-2005, at 0:09, Steve Kellock wrote:> The "Testing The Rails" tutorial is now up-to-date covering the new > functional test api in version 0.11+. > > Lemme know if there''s any issues.This is gorgeous. Great thanks. <unrelated whining>If someone would be selling a hardware Rails Test Suite Accelerator I would buy it</unrelated whining> -- Julian "Julik" Tarkhanov
On 5/19/05, Julian ''Julik'' Tarkhanov <listbox-RY+snkucC20@public.gmane.org> wrote:> > On 19-mei-2005, at 0:09, Steve Kellock wrote: > > > The "Testing The Rails" tutorial is now up-to-date covering the new > > functional test api in version 0.11+. > > > > Lemme know if there''s any issues. > > This is gorgeous. Great thanks.Seconded, I''ve always been a little grey on the controller testing and this covered it really well.> > <unrelated whining>If someone would be selling a hardware Rails Test > Suite Accelerator I would buy it</unrelated whining>What parts of your test are running slowly? Have you seen the thread about sqlite and ram drive performance?> -- > Julian "Julik" Tarkhanov > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Steve Kellock wrote:>The "Testing The Rails" tutorial is now up-to-date covering the new >functional test api in version 0.11+. > > >Excellent! Any recommendation on the best way to print an entire section of the wiki (I know you can output rdoc and yaml, but I''d like to keep the same formatting)?
Julian ''Julik'' Tarkhanov
2005-May-19 03:30 UTC
Re: Speeding up tests [Was:] Ye Olde Testing Tutorial
On 19-mei-2005, at 2:02, Michael Koziarski wrote:> >> >> <unrelated whining>If someone would be selling a hardware Rails Test >> Suite Accelerator I would buy it</unrelated whining> >> > > What parts of your test are running slowly? Have you seen the thread > about sqlite and ram drive performance?Nope, maybe it was before I joined the list. Can you point me to it? My units are running slowly, the reloading of fixtures seems to be the culprit. I might start using transactional fixtures (but then again - I won''t be able to use transactions in my core app because the fixtures will be stealing the transaction from me). And how one does make a RAM disk on OS X (I''m a little rusty on this since my classic days - I''ve been happy with the opposite when RAM was in short supply). -- Julian "Julik" Tarkhanov
Michael Koziarski
2005-May-19 05:10 UTC
Re: Re: Speeding up tests [Was:] Ye Olde Testing Tutorial
On 5/19/05, Julian ''Julik'' Tarkhanov <listbox-RY+snkucC20@public.gmane.org> wrote:> > On 19-mei-2005, at 2:02, Michael Koziarski wrote: > > > >> > >> <unrelated whining>If someone would be selling a hardware Rails Test > >> Suite Accelerator I would buy it</unrelated whining> > >> > > > > What parts of your test are running slowly? Have you seen the thread > > about sqlite and ram drive performance? > > Nope, maybe it was before I joined the list. Can you point me to it? > My units are running slowly, the reloading of fixtures seems to be > the culprit. I might start using transactional fixtures (but then > again - I won''t be able to use transactions in my core app because > the fixtures will be stealing the transaction from me). > > And how one does make a RAM disk on OS X (I''m a little rusty on this > since my classic days - I''ve been happy with the opposite when RAM > was in short supply).If you search the archives (http://news.gmane.org/gmane.comp.lang.ruby.rails) for the following subject sqlite3 + ram drive => 3 times faster> -- > Julian "Julik" Tarkhanov > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
On May 18, 2005, at 8:30 PM, Julian ''Julik'' Tarkhanov wrote:> On 19-mei-2005, at 2:02, Michael Koziarski wrote: >>> <unrelated whining>If someone would be selling a hardware Rails Test >>> Suite Accelerator I would buy it</unrelated whining> >> What parts of your test are running slowly? Have you seen the thread >> about sqlite and ram drive performance? > Nope, maybe it was before I joined the list. Can you point me to > it? My units are running slowly, the reloading of fixtures seems to > be the culprit. I might start using transactional fixtures (but > then again - I won''t be able to use transactions in my core app > because the fixtures will be stealing the transaction from me).Stealing the transaction? In Active Record (and most other ORMs), nested transactions are flattened. The transaction method is similar to the "Requires" declaration in EJB: a transaction is begun only if one is not already active. By all means, use transactional fixtures. Turn off instantiated fixtures for additional speedup. Best, jeremy
Sam Newman
2005-May-19 08:05 UTC
Re: Re: Speeding up tests [Was:] Ye Olde Testing Tutorial
On 5/19/05, Julian ''Julik'' Tarkhanov <listbox-RY+snkucC20@public.gmane.org> wrote:> And how one does make a RAM disk on OS X (I''m a little rusty on this > since my classic days - I''ve been happy with the opposite when RAM > was in short supply).Try: http://www.cutolo.tk/ for creating a RAM disk on OSX. -- sam http://www.magpiebrain.com/
Sam Newman
2005-May-19 08:06 UTC
Re: Re: Speeding up tests [Was:] Ye Olde Testing Tutorial
That link seems dead - try http://www.macupdate.com/info.php/id/15735 instead... On 5/19/05, Sam Newman <sam.newman-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 5/19/05, Julian ''Julik'' Tarkhanov <listbox-RY+snkucC20@public.gmane.org> wrote: > > And how one does make a RAM disk on OS X (I''m a little rusty on this > > since my classic days - I''ve been happy with the opposite when RAM > > was in short supply). > > Try: http://www.cutolo.tk/ for creating a RAM disk on OSX. > > -- > sam > http://www.magpiebrain.com/ >-- sam http://www.magpiebrain.com/
On 19-mei-2005, at 7:55, Jeremy Kemper wrote:> > Stealing the transaction? In Active Record (and most other ORMs), > nested transactions are flattened. The transaction method is > similar to the "Requires" declaration in EJB: a transaction is > begun only if one is not already active. > > By all means, use transactional fixtures. Turn off instantiated > fixtures for additional speedup.Wow! I didn''t know that - I come from PHP background where (even with some DBALs) you always have to watch out if you open a transaction. -- Julian "Julik" Tarkhanov
Jeremy Kemper wrote:> Stealing the transaction? In Active Record (and most other ORMs), > nested transactions are flattened. The transaction method is similar > to the "Requires" declaration in EJB: a transaction is begun only if > one is not already active. > > By all means, use transactional fixtures. Turn off instantiated > fixtures for additional speedup.Hmm.. Can Active Record do nested transactions? AFAIK, PostgreSQL 8.0+ does support nested transactions. (a.k.a. savepoints in Postgres). If AR doesn''t support them, we have to write our own support. - Adam
On May 19, 2005, at 4:07 PM, Adam Majer wrote:> Jeremy Kemper wrote: >> Stealing the transaction? In Active Record (and most other ORMs), >> nested transactions are flattened. The transaction method is similar >> to the "Requires" declaration in EJB: a transaction is begun only if >> one is not already active. >> >> By all means, use transactional fixtures. Turn off instantiated >> fixtures for additional speedup. > > Hmm.. Can Active Record do nested transactions? > > AFAIK, PostgreSQL 8.0+ does support nested transactions. (a.k.a. > savepoints in Postgres). If AR doesn''t support them, we have to write > our own support.No. However, I have some code that emulates them using savepoints, a feature supported in one form or another by most of the AR databases. But I realized that nesting transactions, for most apps, is slow and unnecessary. You rarely need partial rollback. Do you have a need? Do you know of any mainstream ORM that supports them well? Best, jeremy
Jeremy Kemper wrote:> On May 19, 2005, at 4:07 PM, Adam Majer wrote: > >> Hmm.. Can Active Record do nested transactions? >> >> AFAIK, PostgreSQL 8.0+ does support nested transactions. (a.k.a. >> savepoints in Postgres). If AR doesn''t support them, we have to write >> our own support. > > > No. However, I have some code that emulates them using savepoints, a > feature supported in one form or another by most of the AR > databases. But I realized that nesting transactions, for most apps, > is slow and unnecessary. You rarely need partial rollback. > > Do you have a need? Do you know of any mainstream ORM that supports > them well?I don''t have a *need* yet, but I realize the importance of savepoints or nested transactions. In many ways, savepoints are a generalized form of nested transactions. These are needed for applications that require atomicity for complex transactions where a failure in one part of business logic doesn''t mean everything failed. For example, financial software needs serializable, nested transactions to do sane accounting. Anytime you have branching in a transaction that you implemented in the database (stored procedures), it is best to use nested transactions. As an example, if you have an application that stores email in a database, 1. Start a transaction to store the email 2. Store information about getting email in log table 3. Split the headers, body into sections. Each header "line" can be one row. Attempt to store. 4. If #3 fails, rollback to #2. Log error message and report 450 and alert the admin 5. Commit If commit fails, report 450 and *call* the admin! Ok, not the best example, but with nested transaction you do not have to worry about programs "stealing" your transactions. I think Postgres 8 has a rather good support for nested transactions.>From the Postgres manual it is clear that Postgres supports nestedtransactions that could be implemented in rails without a problem. This means you could have, transaction() transaction() transaction() rollback() transaction() commit() commit() commit() That is, if no transaction is open, you BEGIN one. Otherwise, rails can just call "SAVEPOINT/RELEASE SAVEPOINT rails_super_savepoint #{@@savepoint_no}" in a recursive fashion. I think adding this type nested transaction support to Rails would be a great step forward! - Adam
On 5/21/05, Adam Majer <adamm-+878OnfSgr5BDgjK7y7TUQ@public.gmane.org> wrote:> I think Postgres 8 has a rather good support for nested transactions. > >From the Postgres manual it is clear that Postgres supports nested > transactions that could be implemented in rails without a problem. This > means you could have, > > transaction() > transaction() > transaction() > rollback() > transaction() > commit() > commit() > commit() > > That is, if no transaction is open, you BEGIN one. Otherwise, rails can > just call "SAVEPOINT/RELEASE SAVEPOINT rails_super_savepoint > #{@@savepoint_no}" in a recursive fashion. > > I think adding this type nested transaction support to Rails would be a > great step forward!I don''t disagree, but out of curiosity what would the behavior be for Rails if such facilities do not exist? Silently not work, throw some "NotImplementedException", something else?
Michael Campbell wrote:>On 5/21/05, Adam Majer <adamm-+878OnfSgr5BDgjK7y7TUQ@public.gmane.org> wrote: > > > >>I think adding this type nested transaction support to Rails would be a >>great step forward! >> >> > >I don''t disagree, but out of curiosity what would the behavior be for >Rails if such facilities do not exist? Silently not work, throw some >"NotImplementedException", something else? > >It could continue to the way it is done right now. It would only work for the databases that support this. I assume people would know which databases they can use with their application(s). For example, the current implementation for MySQL ignores errors if transactions are not supported by the backend. Also, the current implementation of transactions in RoR is to flatten transactions. - Adam
On May 21, 2005, at 12:36 PM, Adam Majer wrote:> Jeremy Kemper wrote: >> On May 19, 2005, at 4:07 PM, Adam Majer wrote: >>> Hmm.. Can Active Record do nested transactions? >>> >>> AFAIK, PostgreSQL 8.0+ does support nested transactions. (a.k.a. >>> savepoints in Postgres). If AR doesn''t support them, we have to >>> write >>> our own support. >> >> No. However, I have some code that emulates them using savepoints, a >> feature supported in one form or another by most of the AR >> databases. But I realized that nesting transactions, for most apps, >> is slow and unnecessary. You rarely need partial rollback. >> >> Do you have a need? Do you know of any mainstream ORM that supports >> them well? > > I don''t have a *need* yet, but I realize the importance of > savepoints or > nested transactions. In many ways, savepoints are a generalized > form of > nested transactions.And in many ways they are not. Some databases (DB2, until recently) treat savepoints as markers of partial progress within a single transaction: you can''t mark a new savepoint before releasing the last one. Most databases (MySQL 4+, PostgreSQL 8+, Oracle, DB2, MSSQL) treat them as poor-man''s nested transactions: you can ensure progress by partial commit/rollback, but you lose transaction isolation. Only a few databases (Oracle, DB2, MSSQL) support true nested transactions. Given these limitations, savepoints are commonly used just to avoid the overhead of starting a new transaction or to explicitly limit the lifetime of a contentious lock (eg, a SELECT ... FOR UPDATE within a savepoint obtains a row lock that is released along with the savepoint.)> These are needed for applications that require > atomicity for complex transactions where a failure in one part of > business logic doesn''t mean everything failed. For example, financial > software needs serializable, nested transactions to do sane > accounting. > Anytime you have branching in a transaction that you implemented in > the > database (stored procedures), it is best to use nested > transactions. As > an example, if you have an application that stores email in a > database,Many DBAs would disagree. It is uncommon to have a nested failure that should not lead to rollback of the root transaction. PL/SQL and T-SQL both provide and encourage error/exception handling; typically, only the top-level stored procs need to manage a root transaction. Financial software does not categorically need serializable nested transactions. A lot of databases don''t even do serializable and those that do are in for locking hell if you use that isolation level exclusively. Read committed and flat transactions are sufficient for most apps, including enterprise-critical financial software.> That is, if no transaction is open, you BEGIN one. Otherwise, rails > can > just call "SAVEPOINT/RELEASE SAVEPOINT rails_super_savepoint > #{@@savepoint_no}" in a recursive fashion. > > I think adding this type nested transaction support to Rails would > be a > great step forward!I''m not so sure. I implemented what you describe above but found it tends to be overused. Most methods want to be called within a transaction but don''t care whether it''s new ("Requires" declaration.) It''s rare that a method must be called within its own transaction ("RequiresNew" declaration) and even then, what if it needs a different isolation level than the root? Then do a savepoint if the isolation level matches; otherwise, start a new transaction if the db supports it or raise an exception. We''d be doing a lot of work to support a feature that''s rarely needed, thus positioning it for overuse. I think it''s a good sign that EJB (and JTA) support flat transactions only, even in EJB 2. If you''re working at this level, you''re probably a DBA writing stored procs anyway (and you''re horrified at the flood of transaction abuse coming in from the new-fangled "RAILS" app the new dev team put together, wishing you''d taken a harder stand against ad-hoc queries.) Tangentially, what do you think of declared transactions? For example: # Probably overly complex. :supported is default. transaction :required => [:save, :update, :delete], :supported => [:find, :exists?], :unsupported => :operates_on_other_db # Reduce to :required. Assume :supported for others. transaction :save, :update, :delete Best, jeremy