This can only be an opinionated answer, but here are my rules of thumb regarding acceptance testing :
test the behavior expected by user
This is, as you mentionned "acceptance" testing : stackholder want to be provided with usual behavior for feature, not to be worried about what happen if something is invalid or user forgot to log in (controller specs already test that).
test what user should see
This is not the place to check if database is in correct state. Test flash messages and maybe what visually changed in a page (an item being or not being anymore in a list).
For example, in your "creating new post" scenario, you could test :
within '#flash_message' do
page.should have_content 'Post created'
end
within '#posts' do
page.should have_content "My new post"
end
You could write more specifics, but it would be duplication with unit tests, which are faster (why to check if Post.count is +1 if you can check Post received call to #create
stub ?). Testing a few texts or elements on your page is enough to tell parts play well together.
Test an actual user behavior
No user "visits todo list item edition page". They begin from home page, then go to todo list, then click "edit" on the line of a specific item.
In your code, you could replace :
visit project_posts_path(project)
with :
def visit_posts
visit '/'
within '#projects' do
first( 'a.posts' ).click
end
end
scenario 'listing posts' do
visit_posts
project.posts.each do |post|
page.should have_content post.title
end
end
This is longer to run, but anyway, after one or two years of existence, your acceptance testing suite will be too long to run to just wait for it, you'll put it on a continuous integration server. And what matters here is to test everything works together as expected, not a specific behavior. There's no better way to do this than to start with home page (or any page an actual user would open directly, like admin home page, for example).