I use Specflow for test automation and I need to test that user can register.
The problem is that there are a lot of fields for registering, around 30.
My script looks something like this:
And user is adding <value1> in the TextBox1 field
And user is adding <value2> in the TextBox2 field
...
And user is adding <value3> in the TextBox3 field
Outline scenario
<value1> <value2> <value3>
Is this a good approach in Specflow or should I compact all in something like this:
And the user registers by filling in all the fields
Avoid phrasing your steps with user interface terminology. Instead focus on the business process of registering a user. For large forms, I find vertical data tables in a step to be very clear and concise. You haven't included much information about the user registration process, so I'll make something up and maybe you can extrapolate to your specific application.
When the user registers with the following information:
| Field | Value |
| First Name | ... |
| Last Name | ... |
| Username | ... |
| Address | ... |
| City | ... |
| State | ... |
The complexity of filling out the large form gets handled in the step definition, and perhaps a "page model" class that knows how to interact with the registration page. Use the Table.CreateInstance<T> extension method to map the table parameter to a strongly typed object in C#.
[When(#"the user registers with the following information:")]
public void WhenTheUserRegistersWithTheFollowingInformation(Table table)
{
var data = table.CreateInstance<RegisterUserDataRow>();
var registrationPage = new RegistrationPage(driver); // pass Selenium driver object
registrationPage.RegisterNewUser(username: data.Username,
firstName: data.FirstName,
lastName: data.LastName,
address: data.Address,
city: data.City,
state: data.State);
}
And the page model class:
public class RegistrationPage
{
public void RegisterNewUser(string username, string firstName, string lastName, string address, string city, string state)
{
UsernameField.SendKeys(username);
FirstNameField.SendKeys(firstName);
...
RegisterButton.Click();
}
}
Related
Is there a way to partially insert an object using PetaPoco or NPoco?
For example, I have a table called Users:
UserId | UserName | UserMail | UserCreationDate
Each one of these columns are NON NULLABLE and have a default value when they are left empty.
In ASP.NET I have a User class, and I use the ORM to insert a new record with only the name:
Dim userData As New User()
userData.UserName = "Jimmy Hendrix"
db.Insert(userData)
I expect the database to look as follows:
UserId | UserName | UserMail | UserCreationDate
12 | Jimmy Hendrix | (DB default)| (DB default)
I want the insert command only insert the name, without inserting the other object properties with the object's default values.
Such as there is a partial update, I want a partial insert.
Is that possible in PetaPoco?
Is there another way to do it by myself without any ORM?
Edit:
Using SQL I can get the job done, but I need to use POCO objects, so I don't want to have to remember the database parameters. I want something like
user.UserName = "Michael"
user.Insert(user)
And it will insert only the UserName, ignoring the other variables. The SQL that I want to be generated in the background is:
"INSERT Users(UserName) VALUES(#UserName)"
(while the #UserName parameter holds the userData.FirstName value)
As you can see, it doesn't take in account the other variables in the class.
Today if I use the insert command, even if I give a value to a single property in the class, NPoco still tries to insert ALL the class variables into the db setting the variables I didn't want to set with the class's default values (which are different from the db default values)
Also, all of the properties are insertable/updateable, so there can't be any ResultColumn types in the class. I want to insert these values but only the ones I declare in that particular instance. All of the properties are available to update and insert but for each instance i insert only what i declare.
I would create a PartialUserForInsert class:
[TableName("Users")]
public class PartialUserForInsert
{
public string UserName { get; set; }
}
Your provided schema does not include a FirstName column.
Assuming the column is mapped to UserName, using the following should insert as expected.
dim sql = new Sql("INSERT Users(UserName) VALUES(#0)", userData.FirstName)
db.Execute(sql)
What I want to do is to create a hierachy of roles a person can have. And do this with Doctrine and Symfony2.
The top of the hierachy would be person. From person there is one subclass called employee and two from this called it_user and telephony_user. Each one of these add a couple of attributes to the baseclass person.
If I understand correctly, with a Single Table Inheritance I would have different rows (one by rol/subclass) for the same person.
I want the same row for the same person, and manage a certain subset of attributes with every class/subclass.
Questions:
Is Single Table Inheritance a good way for doing this? Any tweak?
Or otherwise is better the classic way with a superclass called person with an aggregation of all the attributes of all roles?
It is better any other way?
Thank you in advance.
If you plan to set different attributes according to person type, then you should use Class Table Inheritance. This inheritance lets you make the following:
Superclass:
Person
- name
- gender
Subclass 1:
Employ extends Person
- manager
- projects
Subclass 2:
TelephonyUser extends Person
- schedule
- foo
- bar
By this way, every model (subclasses) is mapped to its table. See how each subclass have custom attributes from each other and sharing parent attributes at the same time.
Single Table Inheritance (STI) and Aggregation
Take a look at following db schema:
-- Uploads table
id | name | size | type | filename
------------------------------------------
1 | upload1 | 43423 | image | foo.gif
2 | upload2 | 64234 | file | hack.txt
3 | upload3 | 76646 | image | bar.gif
File and Image are two subclasses of Upload class according to type column. As you see, both of them have the same attributes with taking care of subclass type. Why? because this Inheritance is wise based in behavior model instead of structure. For example, you can manage the attribute data differently for each class:
// In file class the content as text should be showen
class File extends Uploads{
// show the file content
public function show(){
echo file_get_contents( $this->filename );
}
}
// In Image class the image should be showen
class File extends Uploads{
// show the file content
public function show(){
echo "<img src='{ $this->filename }' alt='' />";
}
}
See how every class having the same attributes they manage them different from each other. But the most relevant here is that all data will be stored in a unique table. So, what you need to do is to model your db squema in order to apply the appropiate Inheritance.
I need to get all documents readable by a specific user. Assuming that the performer user is admin, Is that possible with "standard" queries or some kind of workaround?
As an example, to be clear, say there are only two documents in the repository and only two users (beside admin). The ACL is something like that:
\ Mike | Bob
doc1 | rw | r
doc2 | r | -
I want to perform a query as admin to get all documents readable by Bob, thus I expect only doc1 as result.
Thanks
I don't think this is possible without traversing the entire collection of search results and inspecting the permissions on each result.
As others have said, if you do the search as the user instead of admin, you'll only get the results the user is allowed to see.
I suppose as admin you could do a search as the user and see what comes back, but if you have multiple users, as in your example, this will become tedious.
The only thing which is possible is to write some Java code to execute the query with another runas user.
Here is a working Java code which extends the default Alfresco webscript behaviour where you can submit a runas parameter. If you create a Java Backend Webscript and implement the runas function and perform a SearchService.query then you're good to go.
#Override
protected void transactionedExecute(final WebScript script,
final WebScriptRequest scriptReq, final WebScriptResponse scriptRes)
throws IOException
{
//already authenticated here
//already pass the authentication
//get the runAs Parameter
String runAs = scriptReq.getParameter(runAsParamName);
final String fixCurrentAuthenticatedUser = authenticationService.getCurrentUserName();
RetryingTransactionCallback<Boolean> exampleWork = new RetryingTransactionCallback<Boolean>()
{
public Boolean execute() throws Exception
{
return authorityService.isAdminAuthority(fixCurrentAuthenticatedUser);
}
};
boolean isAdmin = retryingTransactionHelper.doInTransaction(exampleWork);
//only admins are allowed to do that
if ( !isAdmin || runAs == null || runAs == "")
{
//ignore runAs
super.transactionedExecute(script, scriptReq, scriptRes);
return;
}
final RunAsRepositoryContainer thisIsThis = this;
RunAsWork<Object> work = new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
super.transactionedExecute(script, scriptReq, scriptRes);
return null;
}
};
AuthenticationUtil.runAs(work, runAs);
}
I am trying to get the private member's value (Text) from NumericUpDown.
public class NumericUpDown
{
private TextBox Text;
...
...
}
I am not understanding why it's not showing as a field. Maybe someone could clarify the difference between fields and members. If it was a field I have found that using reflection I can get it by:
typeof(NumericUpDown).GetField("Text", BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this) As TextBox
but it's a member so I have to get the MemberInfo by:
typeof(NumericUpDown).GetMember("Text", BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(0)
this does not return the value, but a string with the type. Which would make sense, because It's the value of the memberinfo, but I want the actual value of the actual object.
Is there any way of retrieving it like FieldInfo.GetValue(object)? Any help or suggestions. Thanks in advance.
This is because you are using Silverlight.
Quote:
Silverlight reflection cannot be used to bypass access level restrictions and (for example) invoke private members.
I am using NHibernate (version 1.2.1) for the first time so I wrote a simple test application (an ASP.NET project) that uses it. In my database I have two tables: Persons and Categories. Each person gets one category, seems easy enough.
| Persons | | Categories |
|--------------| |--------------|
| Id (PK) | | Id (PK) |
| Firstname | | CategoryName |
| Lastname | | CreatedTime |
| CategoryId | | UpdatedTime |
| CreatedTime | | Deleted |
| UpdatedTime |
| Deleted |
The Id, CreatedTime, UpdatedTime and Deleted attributes are a convention I use in all my tables, so I have tried to bring this fact into an additional abstraction layer. I have a project DatabaseFramework which has three important classes:
Entity: an abstract class that defines these four properties. All 'entity objects' (in this case Person and Category) must inherit Entity.
IEntityManager: a generic interface (type parameter as Entity) that defines methods like Load, Insert, Update, etc.
NHibernateEntityManager: an implementation of this interface using NHibernate to do the loading, saving, etc.
Now, the Person and Category classes are straightforward, they just define the attributes of the tables of course (keeping in mind that four of them are in the base Entity class).
Since the Persons table is related to the Categories table via the CategoryId attribute, the Person class has a Category property that holds the related category. However, in my webpage, I will also need the name of this category (CategoryName), for databinding purposes for example. So I created an additional property CategoryName that returns the CategoryName property of the current Category property, or an empty string if the Category is null:
Namespace Database
Public Class Person
Inherits DatabaseFramework.Entity
Public Overridable Property Firstname As String
Public Overridable Property Lastname As String
Public Overridable Property Category As Category
Public Overridable ReadOnly Property CategoryName As String
Get
Return If(Me.Category Is Nothing, _
String.Empty, _
Me.Category.CategoryName)
End Get
End Property
End Class
End Namespace
I am mapping the Person class using this mapping file. The many-to-one relation was suggested by Yads in another thread:
<id name="Id" column="Id" type="int" unsaved-value="0">
<generator class="identity" />
</id>
<property name="CreatedTime" type="DateTime" not-null="true" />
<property name="UpdatedTime" type="DateTime" not-null="true" />
<property name="Deleted" type="Boolean" not-null="true" />
<property name="Firstname" type="String" />
<property name="Lastname" type="String" />
<many-to-one name="Category" column="CategoryId" class="NHibernateWebTest.Database.Category, NHibernateWebTest" />
(I can't get it to show the root node, this forum hides it, I don't know how to escape the html-like tags...)
The final important detail is the Load method of the NHibernateEntityManager implementation. (This is in C# as it's in a different project, sorry about that).
I simply open a new ISession (ISessionFactory.OpenSession) in the GetSession method and then use that to fill an EntityCollection(Of TEntity) which is just a collection inheriting System.Collections.ObjectModel.Collection(Of T).
public virtual EntityCollection< TEntity > Load()
{
using (ISession session = this.GetSession())
{
var entities = session
.CreateCriteria(typeof (TEntity))
.Add(Expression.Eq("Deleted", false))
.List< TEntity >();
return new EntityCollection< TEntity >(entities);
}
}
(Again, I can't get it to format the code correctly, it hides the generic type parameters, probably because it reads the angled symbols as a HTML tag..? If you know how to let me do that, let me know!)
Now, the idea of this Load method is that I get a fully functional collection of Persons, all their properties set to the correct values (including the Category property, and thus, the CategoryName property should return the correct name).
However, it seems that is not the case. When I try to data-bind the result of this Load method to a GridView in ASP.NET, it tells me this:
Property accessor 'CategoryName' on object 'NHibernateWebTest.Database.Person' threw the following exception:'Could not initialize proxy - the owning Session was closed.'
The exception occurs on the DataBind method call here:
public virtual void LoadGrid()
{
if (this.Grid == null) return;
this.Grid.DataSource = this.Manager.Load();
this.Grid.DataBind();
}
Well, of course the session is closed, I closed it via the using block. Isn't that the correct approach, should I keep the session open? And for how long? Can I close it after the DataBind method has been run?
In each case, I'd really like my Load method to just return a functional collection of items. It seems to me that it is now only getting the Category when it is required (eg, when the GridView wants to read the CategoryName, which wants to read the Category property), but at that time the session is closed. Is that reasoning correct?
How do I stop this behavior? Or shouldn't I? And what should I do otherwise?
Thanks!
Setting lazy loading = false in your mapping will solve the error. It would be a better practice though to tell NHibernate in your load query that you want to fetch the child collection of categories eagerly.
For a criteia query something like .SetFetchMode("Categories", FetchMode.Eager) should work.
Here is a link that gives some insight into the so called "n + 1" problem, how lazy loading relates to it, and how NHibernate is meant to be used.
HTH,
Berryl
something like this:
var entities = session
.CreateCriteria<TEntity>()
.SetFetchMode("Categories", FetchMode.Eager)
.Add(Expression.Eq("Deleted", false))
.List< TEntity >();
The problem is that when your entity is lazy loaded. The query only gets the items that it currently needs. So in your case it gets the Person object. Then when you access any linked entities, it fires off another query. It uses proxy objects for this that know about the Session that was used. You are only keeping the Session open for the Load and then you're closing it.
This is actually bad practice in the NHibernate world. You want to keep the session alive for a period known as a unit of work. This gives you a lot of benefits, like caching and lazy loading. Consequently you can disable lazy loading it should work. Although I'd recommend modifying your loader class if at all possiblem