diff --git tests/phpunit/testcases/activity/class-bp-activity-template.php tests/phpunit/testcases/activity/class-bp-activity-template.php
index e69de29..6ef897b 100644
--- tests/phpunit/testcases/activity/class-bp-activity-template.php
+++ tests/phpunit/testcases/activity/class-bp-activity-template.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * @group activity
+ * @group BP_Activity_Template
+ */
+class BP_Tests_BP_Activity_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function activities_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'page'              => 1,
+			'per_page'          => 20,
+			'page_arg'          => 'acpage',
+			'max'               => false,
+			'count_total'       => false,
+			'sort'              => false,
+			'include'           => false,
+			'exclude'           => false,
+			'in'                => false,
+			'filter'            => false,
+			'scope'             => false,
+			'search_terms'      => false,
+			'meta_query'        => false,
+			'date_query'        => false,
+			'filter_query'      => false,
+			'display_comments'  => 'threaded',
+			'show_hidden'       => false,
+			'spam'              => 'ham_only',
+			'update_meta_cache' => true,
+		) );
+	}
+
+	/**
+	 * @group BP_Activity_Template
+	 */
+	public function test_bp_activity_template() {
+		$u1 = $this->factory->user->create();
+		$u2 = $this->factory->user->create();
+
+		$activities = $this->factory->activity->create_many( 4, array(
+			'type'    => 'activity_template_test',
+			'user_id' => $u1
+		) );
+
+		$comments = array();
+
+		foreach ( $activities as $aid ) {
+			$comments[] = $this->factory->activity->create( array(
+				'item_id' => $aid,
+				'type'    => 'activity_comment',
+				'user_id' => $u2,
+			) );
+		}
+
+		// Set pagination
+		$r = $this->activities_get_args( array(
+			'per_page'    => 2,
+			'filter'      => array( 'action' => 'activity_template_test' ),
+			'count_total' => true,
+		) );
+
+		$activities_page_1 = new BP_Activity_Template( $r );
+
+		$found_activities = $activities_page_1->activities;
+
+		$this->assertEquals( 2, count( $found_activities ) );
+		$this->assertEquals( 2, $activities_page_1->activity_count );
+		$this->assertEquals( 4, $activities_page_1->total_activity_count );
+
+		// Check some extra properties
+		$this->assertTrue( isset( $activities_page_1->disable_blogforum_replies ) );
+		$this->assertTrue( isset( $activities_page_1->my_favs ) );
+		$this->assertTrue( isset( $activities_page_1->has_more_items ) );
+		$this->assertTrue( isset( $activities_page_1->full_name ) );
+
+		preg_match( '/\?acpage=(.*)\'/', $activities_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->activities_get_args( array(
+			'per_page' => 2,
+			'page'     => intval( $matches[1] ),
+			'filter'   => array( 'action' => 'activity_template_test' ),
+		) );
+
+		$activities_page_2 = new BP_Activity_Template( $r );
+
+		foreach( $activities_page_2->activities as $fa ) {
+			$found_activities[] = $fa;
+		}
+
+		$found_activities = array_map( 'intval', wp_list_pluck( $found_activities, 'id' ) );
+		$this->assertEqualSets( $activities, $found_activities );
+
+		// Check comments are fetching parents
+		$r = $this->activities_get_args( array(
+			'filter'           => array( 'action' => 'activity_comment' ),
+			'include'          => implode( ',', $comments ),
+			'display_comments' => 'stream'
+		) );
+
+		$activity_comments = new BP_Activity_Template( $r );
+		$this->assertEqualSets( wp_list_pluck( $activity_comments->activities, 'item_id' ), wp_list_pluck( $activity_comments->activity_parents, 'id' ) );
+	}
+}
diff --git tests/phpunit/testcases/blogs/class-bp-blogs-template.php tests/phpunit/testcases/blogs/class-bp-blogs-template.php
index e69de29..61c2632 100644
--- tests/phpunit/testcases/blogs/class-bp-blogs-template.php
+++ tests/phpunit/testcases/blogs/class-bp-blogs-template.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * @group BP_Blogs_Template
+ */
+class BP_Tests_BP_Blogs_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function blogs_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'type'              => 'active',
+			'page_arg'          => 'bpage',
+			'page'              => 1,
+			'per_page'          => 20,
+			'max'               => false,
+			'user_id'           => 0,
+			'include_blog_ids'  => false,
+			'search_terms'      => '',
+			'update_meta_cache' => true
+		) );
+	}
+
+	/**
+	 * @group BP_Blogs_Template
+	 */
+	public function test_bp_blogs_template() {
+		if ( ! is_multisite() ) {
+			return;
+		}
+
+		// Default arguments
+		$r = $this->blogs_get_args();
+
+		// Get the blogs
+		$blogs_empty = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'] );
+
+		$this->assertEquals( 0, count( $blogs_empty->blogs ) );
+		$this->assertEquals( 0, $blogs_empty->blog_count );
+		$this->assertEquals( 0, $blogs_empty->total_blog_count );
+
+		$blogs = array(
+			'test_loop1' => array( 'blogname' => 'TestLoop1', 'blogdescription' => 'TestLoop1 Description', 'public' => 1 ),
+			'test_loop2' => array( 'blogname' => 'TestLoop2', 'blogdescription' => 'TestLoop2 Description', 'public' => 1 ),
+		);
+
+		// Not setting user login or email generates errors in unit tests ?
+		$u_test_loop = array(
+			'test_loop1' => $this->factory->user->create( array( 'role' => '' ) ),
+			'test_loop2' => $this->factory->user->create( array( 'role' => '' ) ),
+		);
+
+		$test_loop = array();
+		$expected_loop = array();
+		$include_blog_ids = array();
+
+		foreach( $blogs as $path => $meta ) {
+
+			$blogs[ $path ]['id'] = $this->factory->blog->create( array(
+				'path'    => '/' . $path,
+				'meta'    => $meta,
+				'user_id' => $u_test_loop[ $path ],
+			) );
+
+			$include_blog_ids[] = $blogs[ $path ]['id'];
+
+			$expected_loop[] = array(
+				'blog_id'       => $blogs[ $path ]['id'],
+				'admin_user_id' => $u_test_loop[ $path ],
+				'name'          => $meta['blogname'],
+				'description'   => $meta['blogdescription'],
+			);
+		}
+
+		$r = $this->blogs_get_args( array(
+			'per_page'         => 1,
+			'include_blog_ids' => $include_blog_ids,
+		) );
+
+		$blogs_page_1 = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'] );
+		$the_blogs = $blogs_page_1->blogs;
+
+		$this->assertEquals( 1, count( $blogs_page_1->blogs ) );
+		$this->assertEquals( 1, $blogs_page_1->blog_count );
+		$this->assertEquals( 2, $blogs_page_1->total_blog_count );
+
+		preg_match( '/\?bpage=(.*)\'/', $blogs_page_1->pag_links, $matches );
+		$r['page'] = intval( $matches[1] );
+
+		$blogs_page_2 = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'] );
+		$the_blogs[] = $blogs_page_2->blogs[0];
+
+		foreach ( $the_blogs as $blog ) {
+			$test_loop[] = array(
+				'blog_id'       => $blog->blog_id,
+				'admin_user_id' => $blog->admin_user_id,
+				'name'          => $blog->name,
+				'description'   => $blog->description,
+			);
+		}
+
+		$this->assertEqualSets( $expected_loop, $test_loop );
+	}
+}
diff --git tests/phpunit/testcases/groups/class-bp-groups-group-members-template.php tests/phpunit/testcases/groups/class-bp-groups-group-members-template.php
index e69de29..685dfb0 100644
--- tests/phpunit/testcases/groups/class-bp-groups-group-members-template.php
+++ tests/phpunit/testcases/groups/class-bp-groups-group-members-template.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * @group groups
+ * @group BP_Groups_Group_Members_Template
+ */
+class BP_Tests_BP_Groups_Group_Members_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function group_members_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'group_id'            => 0,
+			'page'                => 1,
+			'per_page'            => 20,
+			'max'                 => false,
+			'exclude'             => false,
+			'exclude_admins_mods' => 1,
+			'exclude_banned'      => 1,
+			'group_role'          => false,
+			'search_terms'        => false,
+			'type'                => 'last_joined',
+		) );
+	}
+
+	/**
+	 * @group BP_Groups_Group_Members_Template
+	 */
+	public function test_bp_groups_group_members_template() {
+		$bp = buddypress();
+		$reset_item_admin = $bp->is_item_admin;
+
+		$u1 = $this->factory->user->create();
+		$g1 = $this->factory->group->create( array( 'creator_id' => $u1 ) );
+
+		$u2 = $this->factory->user->create();
+		$u3 = $this->factory->user->create();
+		$u4 = $this->factory->user->create();
+
+		// Add users to the group
+		groups_join_group( $g1, $u2 );
+		groups_join_group( $g1, $u3 );
+		groups_join_group( $g1, $u4 );
+
+		// Set the item admin
+		$bp->is_item_admin = true;
+
+		// Promote u2 to admin
+		groups_promote_member( $u2, $g1, 'admin' );
+
+		// Promote u3 to mod
+		groups_promote_member( $u3, $g1, 'mod' );
+
+		// Set pagination
+		$r = $this->group_members_get_args( array(
+			'group_id'            => $g1,
+			'per_page'            => 2,
+			'exclude_admins_mods' => 0
+		) );
+
+		$group_members_page_1 = new BP_Groups_Group_Members_Template( $r );
+		$members = $group_members_page_1->members;
+
+		$this->assertEquals( 2, count( $group_members_page_1->members ) );
+		$this->assertEquals( 2, $group_members_page_1->member_count );
+		$this->assertEquals( 4, $group_members_page_1->total_member_count );
+
+		preg_match( '/\?mlpage=(.*)\'/', $group_members_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->group_members_get_args( array(
+			'per_page'            => 2,
+			'group_id'            => $g1,
+			'exclude_admins_mods' => 0,
+			'page'                => intval( $matches[1] ),
+		) );
+
+		$group_members_page_2 = new BP_Groups_Group_Members_Template( $r );
+
+		foreach ( $group_members_page_2->members as $member ) {
+			$members[] = $member;
+		}
+
+		$expected = array( $u1, $u2, $u3, $u4 );
+		$tested = array_map( 'intval', wp_list_pluck( $members, 'ID' ) );
+
+		$this->assertEqualSets( $tested, $expected );
+
+		// Get admins
+		$r = $this->group_members_get_args( array(
+			'group_id'   => $g1,
+			'group_role' => 'admin'
+		) );
+
+		$group_admins = new BP_Groups_Group_Members_Template( $r );
+
+		$expected = array( $u1, $u2 );
+		$tested = array_map( 'intval', wp_list_pluck( $group_admins->members, 'ID' ) );
+
+		$this->assertEqualSets( $tested, $expected );
+
+		// Get mods
+		$r = $this->group_members_get_args( array(
+			'group_id'   => $g1,
+			'group_role' => 'mod'
+		) );
+
+		$group_mods = new BP_Groups_Group_Members_Template( $r );
+
+		$expected = array( $u3 );
+		$tested = array_map( 'intval', wp_list_pluck( $group_mods->members, 'ID' ) );
+
+		$this->assertEqualSets( $tested, $expected );
+
+		// Ban u4 & demote u2, u3
+		groups_ban_member( $u4, $g1 );
+		groups_demote_member( $u2, $g1 );
+		groups_demote_member( $u3, $g1 );
+
+		// Get users
+		$r = $this->group_members_get_args( array(
+			'group_id'   => $g1,
+		) );
+
+		$group_users = new BP_Groups_Group_Members_Template( $r );
+
+		$expected = array( $u2, $u3 );
+		$tested = array_map( 'intval', wp_list_pluck( $group_users->members, 'ID' ) );
+
+		$this->assertEqualSets( $tested, $expected );
+
+		// Reset the item admin
+		$bp->is_item_admin = $reset_item_admin;
+	}
+}
diff --git tests/phpunit/testcases/groups/class-bp-groups-invite-template.php tests/phpunit/testcases/groups/class-bp-groups-invite-template.php
index e69de29..8cf46cc 100644
--- tests/phpunit/testcases/groups/class-bp-groups-invite-template.php
+++ tests/phpunit/testcases/groups/class-bp-groups-invite-template.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @group groups
+ * @group BP_Groups_Invite_Template
+ */
+class BP_Tests_BP_Groups_Invite_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function group_invites_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'group_id' => false,
+			'user_id'  => 0,
+			'per_page' => false,
+			'page'     => 1,
+		) );
+	}
+
+	/**
+	 * @group BP_Groups_Invite_Template
+	 */
+	public function test_bp_groups_invite_template() {
+		$u1 = $this->factory->user->create();
+		$g1 = $this->factory->group->create( array( 'creator_id' => $u1 ) );
+
+		$friends = array(
+			'u2' => $this->factory->user->create(),
+			'u3' => $this->factory->user->create(),
+			'u4' => $this->factory->user->create(),
+		);
+
+		// request friendship
+		foreach ( $friends as $fr ) {
+			friends_add_friend( $fr, $u1 );
+		}
+
+		// accept friendship
+		$old_user = get_current_user_id();
+		$this->set_current_user( $u1 );
+
+		foreach ( $friends as $fa ) {
+			friends_accept_friendship( friends_get_friendship_id( $fa, $u1 ) );
+
+			// Then invite each user
+			groups_invite_user( array(
+				'user_id'    => $fa,
+				'group_id'   => $g1,
+				'inviter_id' => $u1,
+			) );
+		}
+
+		// Restore current user
+		$this->set_current_user( $old_user );
+
+		// Set pagination
+		$r = $this->group_invites_get_args( array(
+			'group_id' => $g1,
+			'user_id'  => $u1,
+			'per_page' => 2,
+		) );
+
+		$group_invites_page_1 = new BP_Groups_Invite_Template( $r );
+		$invites = $group_invites_page_1->invites;
+
+		$this->assertEquals( 2, count( $group_invites_page_1->invites ) );
+		$this->assertEquals( 2, $group_invites_page_1->invite_count );
+		$this->assertEquals( 3, $group_invites_page_1->total_invite_count );
+
+		// Make sure the invite_data property is set
+		$this->assertEqualSets( $group_invites_page_1->invites, wp_list_pluck( $group_invites_page_1->invite_data, 'ID' ) );
+
+		preg_match( '/\?invitepage=(.*)\'/', $group_invites_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->group_invites_get_args( array(
+			'group_id' => $g1,
+			'user_id'  => $u1,
+			'per_page' => 2,
+			'page'     => intval( $matches[1] ),
+		) );
+
+		$group_invites_page_2 = new BP_Groups_Invite_Template( $r );
+
+		// Make sure the invite_data property is set
+		$this->assertEqualSets( $group_invites_page_2->invites, wp_list_pluck( $group_invites_page_2->invite_data, 'ID' ) );
+
+		$invites[] = $group_invites_page_2->invites[0];
+		$invited = array_map( 'intval', $invites );
+		$this->assertEqualSets( $friends, $invited );
+
+		// Check the_invite()
+		$group_invites_page_2->the_invite();
+		$this->assertSame( $group_invites_page_2->invites[0], $group_invites_page_2->invite->user->ID );
+	}
+}
diff --git tests/phpunit/testcases/groups/class-bp-groups-membership-requests-template.php tests/phpunit/testcases/groups/class-bp-groups-membership-requests-template.php
index e69de29..5c51ef2 100644
--- tests/phpunit/testcases/groups/class-bp-groups-membership-requests-template.php
+++ tests/phpunit/testcases/groups/class-bp-groups-membership-requests-template.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * @group groups
+ * @group BP_Groups_Membership_Requests_Template
+ */
+class BP_Tests_BP_Groups_Membership_Requests_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function group_requests_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'group_id' => 0,
+			'per_page' => 10,
+			'page'     => 1,
+			'max'      => false
+		) );
+	}
+
+	/**
+	 * @group BP_Groups_Membership_Requests_Template
+	 */
+	public function test_bp_groups_membership_requests_template() {
+		$bp = buddypress();
+		$reset_item_admin = $bp->is_item_admin;
+
+		$u1 = $this->factory->user->create();
+		$g1 = $this->factory->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) );
+
+		$u2 = $this->factory->user->create();
+		$u3 = $this->factory->user->create();
+		$u4 = $this->factory->user->create();
+
+		// Users are sending requests
+		groups_send_membership_request( $u2, $g1 );
+		groups_send_membership_request( $u3, $g1 );
+		groups_send_membership_request( $u4, $g1 );
+
+		// Set pagination
+		$r = $this->group_requests_get_args( array(
+			'group_id' => $g1,
+			'per_page' => 2,
+		) );
+
+		$group_requests_page_1 = new BP_Groups_Membership_Requests_Template( $r );
+		$requests = $group_requests_page_1->requests;
+
+		$this->assertEquals( 2, count( $group_requests_page_1->requests ) );
+		$this->assertEquals( 2, $group_requests_page_1->request_count );
+		$this->assertEquals( 3, $group_requests_page_1->total_request_count );
+
+		preg_match( '/\?mrpage=(.*)\'/', $group_requests_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->group_requests_get_args( array(
+			'group_id' => $g1,
+			'per_page' => 2,
+			'page'     => intval( $matches[1] ),
+		) );
+
+		$group_requests_page_2 = new BP_Groups_Membership_Requests_Template( $r );
+
+		$requests[] = $group_requests_page_2->requests[0];
+
+		$expected = array( $u2, $u3, $u4 );
+		$tested = array_map( 'intval', wp_list_pluck( $requests, 'ID' ) );
+
+		$this->assertEqualSets( $tested, $expected );
+
+		// Check Compatibility with legacy format of request data objects
+		$this->assertEqualSets( wp_list_pluck( $requests, 'id' ), wp_list_pluck( $requests, 'membership_id' ) );
+
+		// Set the item admin
+		$bp->is_item_admin = true;
+
+		// Accept all requests
+		groups_accept_all_pending_membership_requests( $g1 );
+
+		$r = $this->group_requests_get_args( array(
+			'group_id' => $g1,
+		) );
+
+		$requests = new BP_Groups_Membership_Requests_Template( $r );
+
+		$this->assertEmpty( $requests->requests );
+
+		// Reset the item admin
+		$bp->is_item_admin = $reset_item_admin;
+	}
+}
diff --git tests/phpunit/testcases/groups/class-bp-groups-template.php tests/phpunit/testcases/groups/class-bp-groups-template.php
index e69de29..68d827f 100644
--- tests/phpunit/testcases/groups/class-bp-groups-template.php
+++ tests/phpunit/testcases/groups/class-bp-groups-template.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * @group BP_Groups_Template
+ */
+class BP_Tests_BP_Groups_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function groups_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'type'              => '',
+			'order'             => 'DESC',
+			'orderby'           => 'last_activity',
+			'page'              => 1,
+			'per_page'          => 20,
+			'max'               => false,
+			'show_hidden'       => false,
+			'page_arg'          => 'grpage',
+			'user_id'           => 0,
+			'slug'              => false,
+			'search_terms'      => false,
+			'meta_query'        => false,
+			'include'           => false,
+			'exclude'           => false,
+			'populate_extras'   => true,
+			'update_meta_cache' => true,
+		) );
+	}
+
+	/**
+	 * @group BP_Groups_Template
+	 */
+	public function test_bp_groups_template_directory() {
+
+		// Default arguments
+		$r = $this->groups_get_args();
+
+		$groups_empty = new BP_Groups_Template( $r );
+
+		$this->assertEquals( 0, count( $groups_empty->groups ) );
+		$this->assertEquals( 0, $groups_empty->group_count );
+		$this->assertEquals( 0, $groups_empty->total_group_count );
+
+		$u1 = $this->factory->user->create();
+		$u2 = $this->factory->user->create();
+		$g1 = $this->factory->group->create( array( 'creator_id' => $u1 ) );
+		$g2 = $this->factory->group->create( array( 'creator_id' => $u2, 'status' => 'private' ) );
+
+		// Add a user to one of the group
+		groups_join_group( $g1, $u2 );
+
+		// Update one of the group's last activity
+		groups_update_groupmeta( $g1, 'last_activity', date( 'Y-m-d H:i:s' , strtotime( '+1 hour' ) ) );
+
+		// Set pagination
+		$r = $this->groups_get_args( array( 'per_page' => 1 ) );
+
+		$groups_page_1 = new BP_Groups_Template( $r );
+		$the_groups = $groups_page_1->groups;
+
+		$this->assertEquals( 1, count( $groups_page_1->groups ) );
+		$this->assertEquals( 1, $groups_page_1->group_count );
+		$this->assertEquals( 2, $groups_page_1->total_group_count );
+
+		preg_match( '/\?grpage=(.*)\'/', $groups_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->groups_get_args( array(
+			'per_page' => 1,
+			'page' => intval( $matches[1] )
+		) );
+
+		$groups_page_2 = new BP_Groups_Template( $r );
+		$the_groups[] = $groups_page_2->groups[0];
+		$expected = array();
+		$groups_loop = array();
+
+		foreach ( $the_groups as $group ) {
+
+			$groups_loop[] = array(
+				'id'                 => $group->id,
+				'creator_id'         => $group->creator_id,
+				'status'             => $group->status,
+				'total_member_count' => $group->total_member_count,
+				'last_activity'      => $group->last_activity,
+			);
+
+			$check_group = groups_get_group( array( 'group_id' => $group->id, 'populate_extras' => true ) );
+
+			$expected[] = array(
+				'id'                 => $check_group->id,
+				'creator_id'         => $check_group->creator_id,
+				'status'             => $check_group->status,
+				'total_member_count' => $check_group->total_member_count,
+				'last_activity'      => $check_group->last_activity,
+			);
+		}
+
+		$this->assertEqualSets( $groups_loop, $expected );
+	}
+
+	/**
+	 * @group BP_Groups_Template
+	 */
+	public function test_bp_groups_template_invites() {
+
+		$u1 = $this->factory->user->create();
+		$u2 = $this->factory->user->create();
+		$g1 = $this->factory->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) );
+		$g2 = $this->factory->group->create( array( 'creator_id' => $u1, 'status' => 'hidden' ) );
+
+		groups_invite_user( array(
+			'user_id'    => $u2,
+			'group_id'   => $g1,
+			'inviter_id' => $u1,
+		) );
+
+		groups_send_invites( $u1, $g1 );
+
+		groups_invite_user( array(
+			'user_id'    => $u2,
+			'group_id'   => $g2,
+			'inviter_id' => $u1,
+		) );
+
+		groups_send_invites( $u1, $g2 );
+
+		// Invites arguments
+		$r = $this->groups_get_args( array(
+			'type'        => 'invites',
+			'user_id'     => $u2,
+			'show_hidden' => true,
+		) );
+
+		$groups_invites = new BP_Groups_Template( $r );
+
+		$this->assertEquals( 2, $groups_invites->total_group_count );
+
+		$this->assertEqualSets( array( $g1, $g2 ), wp_list_pluck( $groups_invites->groups, 'id' ) );
+	}
+
+	/**
+	 * @group BP_Groups_Template
+	 */
+	public function test_bp_groups_template_single_group() {
+
+		$u = $this->factory->user->create();
+		$g = $this->factory->group->create( array( 'creator_id' => $u ) );
+
+		$group = groups_get_group( array( 'group_id' => $g ) );
+
+		// Single group arguments
+		$r = $this->groups_get_args( array(
+			'type' => 'single-group',
+			'slug' => $group->slug,
+		) );
+
+		$groups_single = new BP_Groups_Template( $r );
+
+		$this->assertEquals( 1, $groups_single->total_group_count );
+		$this->assertTrue( $groups_single->single_group );
+		$this->assertEquals( $g, $groups_single->groups[0]->id );
+	}
+}
diff --git tests/phpunit/testcases/members/class-bp-core-members-template.php tests/phpunit/testcases/members/class-bp-core-members-template.php
index e69de29..bc6d1a6 100644
--- tests/phpunit/testcases/members/class-bp-core-members-template.php
+++ tests/phpunit/testcases/members/class-bp-core-members-template.php
@@ -0,0 +1,215 @@
+<?php
+/**
+ * @group members
+ * @group BP_Core_Members_Template
+ */
+class BP_Tests_BP_Core_Members_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function members_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'type'            => 'active',
+			'page'            => 1,
+			'per_page'        => 20,
+			'max'             => false,
+			'user_id'         => 0,
+			'search_terms'    => null,
+			'include'         => false,
+			'populate_extras' => true,
+			'exclude'         => false,
+			'meta_key'        => false,
+			'meta_value'      => false,
+			'page_arg'        => 'upage',
+			'member_type'     =>'',
+		) );
+	}
+
+	/**
+	 * @group BP_Core_Members_Template
+	 */
+	public function test_bp_core_members_template_active() {
+
+		$members = array(
+			'u1' => $this->factory->user->create(),
+			'u2' => $this->factory->user->create(),
+			'u3' => $this->factory->user->create(),
+			'u4' => $this->factory->user->create(),
+		);
+
+		// Set pagination
+		$r = $this->members_get_args( array(
+			'per_page' => 2,
+		) );
+
+		$members_page_1 = new BP_Core_Members_Template(
+			$r['type'],
+			$r['page'],
+			$r['per_page'],
+			$r['max'],
+			$r['user_id'],
+			$r['search_terms'],
+			$r['include'],
+			$r['populate_extras'],
+			$r['exclude'],
+			$r['meta_key'],
+			$r['meta_value'],
+			$r['page_arg'],
+			$r['member_type']
+		);
+
+		$found_members = $members_page_1->members;
+
+		$this->assertEquals( 2, count( $found_members ) );
+		$this->assertEquals( 2, $members_page_1->member_count );
+		$this->assertEquals( 4, $members_page_1->total_member_count );
+
+		preg_match( '/\?upage=(.*)\'/', $members_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->members_get_args( array(
+			'per_page' => 2,
+			'page'     => intval( $matches[1] ),
+		) );
+
+		$members_page_2 = new BP_Core_Members_Template(
+			$r['type'],
+			$r['page'],
+			$r['per_page'],
+			$r['max'],
+			$r['user_id'],
+			$r['search_terms'],
+			$r['include'],
+			$r['populate_extras'],
+			$r['exclude'],
+			$r['meta_key'],
+			$r['meta_value'],
+			$r['page_arg'],
+			$r['member_type']
+		);
+
+		foreach( $members_page_2->members as $fm ) {
+			$found_members[] = $fm;
+		}
+
+		$found_members = array_map( 'intval', wp_list_pluck( $found_members, 'ID' ) );
+
+		$this->assertEqualSets( $members, $found_members );
+	}
+
+	/**
+	 * @group BP_Core_Members_Template
+	 */
+	public function test_bp_core_members_template_by_letter() {
+		$reset_request = $_REQUEST;
+		$_REQUEST['letter'] = 'b';
+
+		$letters = array(
+			'u1' => $this->factory->user->create( array(
+				'user_login'    => 'bfoou1',
+				'user_nicename' => 'bfoo-u1',
+			) ),
+			'u2' => $this->factory->user->create( array(
+				'user_login'    => 'bbaru2',
+				'user_nicename' => 'bbar-u2',
+			) ),
+			'u3' => $this->factory->user->create( array(
+				'user_login'    => 'bzoou3',
+				'user_nicename' => 'bzoo-u3',
+			) ),
+			'u4' => $this->factory->user->create( array(
+				'user_login'    => 'balu4',
+				'user_nicename' => 'bal-u4',
+			) ),
+		);
+
+		// Set pagination
+		$r = $this->members_get_args( array(
+			'exclude' => $letters['u2'],
+		) );
+
+		$letters_loop = new BP_Core_Members_Template(
+			$r['type'],
+			$r['page'],
+			$r['per_page'],
+			$r['max'],
+			$r['user_id'],
+			$r['search_terms'],
+			$r['include'],
+			$r['populate_extras'],
+			$r['exclude'],
+			$r['meta_key'],
+			$r['meta_value'],
+			$r['page_arg'],
+			$r['member_type']
+		);
+
+		$this->assertEquals( 3, $letters_loop->member_count );
+		$this->assertEquals( 3, $letters_loop->total_member_count );
+
+		$letter_members = array_map( 'intval', wp_list_pluck( $letters_loop->members, 'id' ) );
+
+		$this->assertEqualSets( array( $letters['u1'], $letters['u3'], $letters['u4'] ), $letter_members );
+
+		// Reset $_REQUEST
+		$_REQUEST = $reset_request;
+	}
+
+	/**
+	 * @group BP_Core_Members_Template
+	 */
+	public function test_bp_core_members_template_include_ids_alphabetical() {
+		// A way to check the "friends loop"
+		$members = array(
+			'u1' => $this->factory->user->create( array(
+				'user_login'    => 'foou1',
+				'user_nicename' => 'foo-u1',
+			) ),
+			'u2' => $this->factory->user->create( array(
+				'user_login'    => 'baru2',
+				'user_nicename' => 'bar-u2',
+			) ),
+			'u3' => $this->factory->user->create( array(
+				'user_login'    => 'zoou3',
+				'user_nicename' => 'zoo-u3',
+			) ),
+			'u4' => $this->factory->user->create( array(
+				'user_login'    => 'alu4',
+				'user_nicename' => 'al-u4',
+			) ),
+		);
+
+		// Set pagination
+		$r = $this->members_get_args( array(
+			'type'    => 'alphabetical',
+			'include' => $members,
+		) );
+
+		$members_loop = new BP_Core_Members_Template(
+			$r['type'],
+			$r['page'],
+			$r['per_page'],
+			$r['max'],
+			$r['user_id'],
+			$r['search_terms'],
+			$r['include'],
+			$r['populate_extras'],
+			$r['exclude'],
+			$r['meta_key'],
+			$r['meta_value'],
+			$r['page_arg'],
+			$r['member_type']
+		);
+
+		$found_members = array_map( 'intval', wp_list_pluck( $members_loop->members, 'ID' ) );
+		$alpha_members = array( $members['u4'], $members['u2'], $members['u1'], $members['u3'] );
+
+		$this->assertEqualSets( $alpha_members, $found_members );
+	}
+}
diff --git tests/phpunit/testcases/messages/class-bp-messages-box-template.php tests/phpunit/testcases/messages/class-bp-messages-box-template.php
index e69de29..302c1be 100644
--- tests/phpunit/testcases/messages/class-bp-messages-box-template.php
+++ tests/phpunit/testcases/messages/class-bp-messages-box-template.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * @group messages
+ * @group BP_Messages_Box_Template
+ */
+class BP_Tests_BP_Messages_Box_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function messages_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'user_id'      => 0,
+			'box'          => 'inbox',
+			'per_page'     => 10,
+			'max'          => false,
+			'type'         => 'all',
+			'search_terms' => '',
+			'page_arg'     => 'mpage',
+		) );
+	}
+
+	/**
+	 * @group BP_Messages_Box_Template
+	 */
+	public function test_bp_messages_box_template() {
+		$reset_get = $_GET;
+
+		$u1 = $this->factory->user->create();
+		$u2 = $this->factory->user->create();
+
+		// send a private message
+		$t1 = messages_new_message( array(
+			'sender_id'  => $u1,
+			'recipients' => array( $u2 ),
+			'subject'    => 'A new message',
+			'content'    => 'Hey there!',
+		) );
+
+		$t2 = messages_new_message( array(
+			'sender_id'  => $u1,
+			'recipients' => array( $u2 ),
+			'subject'    => 'A new message',
+			'content'    => 'Hey there!',
+		) );
+
+		// Send a notice
+		$notice            = new BP_Messages_Notice;
+		$notice->subject   = 'notice subject';
+		$notice->message   = 'notice message';
+		$notice->date_sent = bp_core_current_time();
+		$notice->is_active = 1;
+		$notice->save();
+
+		/** Inbox *********************************************************************/
+
+		$received = array();
+
+		// Set pagination
+		$r = $this->messages_get_args( array(
+			'user_id'  => $u2,
+			'per_page' => 1,
+		) );
+
+		$inbox_messages_page_1 = new BP_Messages_Box_Template(
+			$r['user_id'],
+			$r['box'],
+			$r['per_page'],
+			$r['max'],
+			$r['type'],
+			$r['search_terms'],
+			$r['page_arg']
+		);
+
+		$this->assertEquals( 1, $inbox_messages_page_1->thread_count );
+		$this->assertEquals( 2, $inbox_messages_page_1->total_thread_count );
+		$received = wp_list_pluck( $inbox_messages_page_1->threads[0]->messages, 'thread_id' );
+
+		preg_match( '/\?mpage=(.*)\'/', $inbox_messages_page_1->pag_links, $matches );
+
+		// Set page
+		$_GET['mpage'] = intval( $matches[1] );
+
+		$inbox_messages_page_2 = new BP_Messages_Box_Template(
+			$r['user_id'],
+			$r['box'],
+			$r['per_page'],
+			$r['max'],
+			$r['type'],
+			$r['search_terms'],
+			$r['page_arg']
+		);
+
+		$received = array_merge( $received, wp_list_pluck( $inbox_messages_page_2->threads[0]->messages, 'thread_id' ) );
+
+		$this->assertEqualSets( array( $t1, $t2 ), array_map( 'intval', $received ) );
+
+		// Check the_message_thread()
+		$inbox_messages_page_2->the_message_thread();
+		$this->assertSame( $u1, intval( $inbox_messages_page_2->thread->last_sender_id ) );
+
+		// Reset the GET var
+		$_GET = $reset_get;
+
+		/** Sentbox *******************************************************************/
+
+		$sent = array();
+
+		// Set pagination
+		$r = $this->messages_get_args( array(
+			'user_id'  => $u1,
+			'box'      => 'sentbox',
+		) );
+
+		$sentbox_messages = new BP_Messages_Box_Template(
+			$r['user_id'],
+			$r['box'],
+			$r['per_page'],
+			$r['max'],
+			$r['type'],
+			$r['search_terms'],
+			$r['page_arg']
+		);
+
+		$this->assertEquals( 2, $sentbox_messages->thread_count );
+		$this->assertEquals( 2, $sentbox_messages->total_thread_count );
+		$sent = wp_list_pluck( $sentbox_messages->threads, 'thread_id' );
+
+		$this->assertEqualSets( array( $t1, $t2 ), array_map( 'intval', $sent ) );
+
+		/** Notice ********************************************************************/
+		$bp = buddypress();
+		$bp_current_action = $bp->current_action;
+
+		// Set notice args
+		$r = $this->messages_get_args( array(
+			'user_id'  => $u1,
+			'box'      => 'notices',
+		) );
+
+		$notice_messages = new BP_Messages_Box_Template(
+			$r['user_id'],
+			$r['box'],
+			$r['per_page'],
+			$r['max'],
+			$r['type'],
+			$r['search_terms'],
+			$r['page_arg']
+		);
+
+		$this->assertEquals( 1, $notice_messages->thread_count );
+		$this->assertEquals( 1, $notice_messages->total_thread_count );
+
+		$active_notice = BP_Messages_Notice::get_active();
+		$notice->deactivate();
+
+		$notice_received = wp_list_pluck( $notice_messages->threads, 'id' );
+		$this->assertSame( array( $active_notice->id ), $notice_received );
+
+		$bp->current_action = 'notices';
+
+		// Check the_message_thread()
+		$notice_messages->the_message_thread();
+		$this->assertTrue( ! isset( $notice_messages->thread->last_sender_id ) );
+
+		// Reset $bp->current_action
+		$bp->current_action = $bp_current_action;
+	}
+}
diff --git tests/phpunit/testcases/messages/class-bp-messages-thread-template.php tests/phpunit/testcases/messages/class-bp-messages-thread-template.php
index e69de29..6ad2101 100644
--- tests/phpunit/testcases/messages/class-bp-messages-thread-template.php
+++ tests/phpunit/testcases/messages/class-bp-messages-thread-template.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * @group messages
+ * @group BP_Messages_Thread_Template
+ */
+class BP_Tests_BP_Messages_Thread_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	/**
+	 * @group BP_Messages_Thread_Template
+	 */
+	public function test_bp_messages_thread_template() {
+		$reset_get = $_GET;
+
+		$u1 = $this->factory->user->create();
+		$u2 = $this->factory->user->create();
+
+		// send a private message
+		$t1 = messages_new_message( array(
+			'sender_id'  => $u1,
+			'recipients' => array( $u2 ),
+			'subject'    => 'A new message',
+			'content'    => 'Hey there!',
+		) );
+
+		messages_new_message( array(
+			'sender_id'  => $u2,
+			'thread_id'  => $t1,
+			'content'    => 'A new reply',
+		) );
+
+		messages_new_message( array(
+			'sender_id'  => $u1,
+			'thread_id'  => $t1,
+			'content'    => 'Another reply',
+		) );
+
+		$message_thread = new BP_Messages_Thread_Template( $t1, 'ASC', array( 'update_meta_cache' => true ) );
+
+		$this->assertEquals( 3, $message_thread->message_count );
+		$senders = wp_list_pluck( $message_thread->thread->messages, 'sender_id' );
+		$this->assertEqualSets( array( $u1, $u2, $u1 ), array_map( 'intval', $senders ) );
+	}
+}
+
diff --git tests/phpunit/testcases/notifications/class-bp-notifications-template.php tests/phpunit/testcases/notifications/class-bp-notifications-template.php
index e69de29..c5b1e37 100644
--- tests/phpunit/testcases/notifications/class-bp-notifications-template.php
+++ tests/phpunit/testcases/notifications/class-bp-notifications-template.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * @group notifications
+ * @group BP_Notifications_Template
+ */
+class BP_Tests_BP_Notifications_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function notifications_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'id'                => false,
+			'user_id'           => 0,
+			'secondary_item_id' => false,
+			'component_name'    => bp_notifications_get_registered_components(),
+			'component_action'  => false,
+			'is_new'            => 1,
+			'search_terms'      => '',
+			'order_by'          => 'date_notified',
+			'sort_order'        => 'DESC',
+			'page'              => 1,
+			'per_page'          => 25,
+			'max'               => false,
+			'page_arg'          => 'npage',
+		) );
+	}
+
+	/**
+	 * @group BP_Notifications_Template
+	 */
+	public function test_bp_notifications_template() {
+
+		$u = $this->factory->user->create();
+
+		$components = array( 'groups', 'messages', 'friends', 'activity' );
+		$notifications = array();
+
+		foreach ( $components as $component ) {
+			$notifications[] = $this->factory->notification->create( array(
+				'component_name' => $component,
+				'user_id' => $u,
+			) );
+		}
+
+		// Set pagination
+		$r = $this->notifications_get_args( array(
+			'per_page' => 2,
+			'order_by' => 'id',
+		) );
+
+		$notifications_page_1 = new BP_Notifications_Template( $r );
+
+		$found_notifications = $notifications_page_1->notifications;
+
+		$this->assertEquals( 2, count( $found_notifications ) );
+		$this->assertEquals( 2, $notifications_page_1->notification_count );
+		$this->assertEquals( 4, $notifications_page_1->total_notification_count );
+
+		preg_match( '/\?npage=(.*)\'/', $notifications_page_1->pag_links, $matches );
+
+		// Set page
+		$r = $this->notifications_get_args( array(
+			'per_page' => 2,
+			'page'     => intval( $matches[1] ),
+			'order_by' => 'id',
+		) );
+
+		$notifications_page_2 = new BP_Notifications_Template( $r );
+
+		foreach( $notifications_page_2->notifications as $fn ) {
+			$found_notifications[] = $fn;
+		}
+
+		$found_notifications = array_map( 'intval', wp_list_pluck( $found_notifications, 'id' ) );
+
+		$this->assertEqualSets( $notifications, $found_notifications );
+	}
+}
diff --git tests/phpunit/testcases/xprofile/class-bp-xprofile-data-template.php tests/phpunit/testcases/xprofile/class-bp-xprofile-data-template.php
index e69de29..7e17ed2 100644
--- tests/phpunit/testcases/xprofile/class-bp-xprofile-data-template.php
+++ tests/phpunit/testcases/xprofile/class-bp-xprofile-data-template.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * @group xprofile
+ * @group BP_XProfile_Data_Template
+ */
+class BP_Tests_BP_XProfile_Data_Template_TestCases extends BP_UnitTestCase {
+
+	public function setUp() {
+		parent::setUp();
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+	}
+
+	protected function xprofile_get_args( $args = array() ) {
+		return wp_parse_args( $args, array(
+			'user_id'                => 0,
+			'profile_group_id'       => false,
+			'hide_empty_groups'      => true,
+			'hide_empty_fields'      => true,
+			'fetch_fields'           => true,
+			'fetch_field_data'       => true,
+			'fetch_visibility_level' => false,
+			'exclude_groups'         => 1,     // exclude the base group
+			'exclude_fields'         => false,
+			'update_meta_cache'      => true,
+		) );
+	}
+
+	/**
+	 * @group BP_XProfile_Data_Template
+	 */
+	public function test_bp_xprofile_data_template() {
+		$u = $this->factory->user->create();
+		$g1 = $this->factory->xprofile_group->create();
+		$g2 = $this->factory->xprofile_group->create();
+
+		$fields = array(
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $g1,
+			) ),
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $g1,
+			) ),
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $g2,
+			) ),
+		);
+
+		$fvalues = array( 'foo', 'bar', 'taz' );
+
+		foreach ( $fields as $k => $f ) {
+			// no value for 2nd field of 1st group
+			if ( 1 == $k ) {
+				continue;
+			}
+
+			xprofile_set_field_data( $f, $u, $fvalues[ $k ] );
+		}
+
+		// Set xprofile args
+		$r = $this->xprofile_get_args( array(
+			'user_id'                => $u,
+			'fetch_visibility_level' => true
+		) );
+
+		$u_profile = new BP_XProfile_Data_Template(
+			$r['user_id'],
+			$r['profile_group_id'],
+			$r['hide_empty_groups'],
+			$r['fetch_fields'],
+			$r['fetch_field_data'],
+			$r['exclude_groups'],
+			$r['exclude_fields'],
+			$r['hide_empty_fields'],
+			$r['fetch_visibility_level'],
+			$r['update_meta_cache']
+		);
+
+		$this->assertEquals( 2, count( $u_profile->groups ) );
+		$this->assertEquals( 2, $u_profile->group_count );
+		$this->assertEqualSets( array( $g1, $g2 ), array_map( 'intval', wp_list_pluck( $u_profile->groups, 'id' ) ) );
+
+		$g_fields = wp_list_pluck( $u_profile->groups, 'fields' );
+		$u_fields = array();
+
+		foreach( $g_fields as $gf ) {
+			$u_fields = array_merge( $u_fields, $gf );
+		}
+
+		$this->assertEqualSets( array( $fields[0], $fields[2] ), array_map( 'intval', wp_list_pluck( $u_fields, 'id' ) ) );
+
+		/** Visibility ****************************************************************/
+
+		xprofile_set_field_visibility_level( $fields[2], $u, 'adminsonly' );
+
+		$u_profile = new BP_XProfile_Data_Template(
+			$r['user_id'],
+			$r['profile_group_id'],
+			$r['hide_empty_groups'],
+			$r['fetch_fields'],
+			$r['fetch_field_data'],
+			$r['exclude_groups'],
+			$r['exclude_fields'],
+			$r['hide_empty_fields'],
+			$r['fetch_visibility_level'],
+			$r['update_meta_cache']
+		);
+
+		$this->assertEquals( 1, $u_profile->group_count );
+		$this->assertEqualSets( array( $g1 ), array_map( 'intval', wp_list_pluck( $u_profile->groups, 'id' ) ) );
+
+		$g_fields = wp_list_pluck( $u_profile->groups, 'fields' );
+		$u_fields = array();
+
+		foreach( $g_fields as $gf ) {
+			$u_fields = array_merge( $u_fields, $gf );
+		}
+
+		$this->assertEqualSets( array( $fields[0] ), array_map( 'intval', wp_list_pluck( $u_fields, 'id' ) ) );
+
+		$old_user = get_current_user_id();
+		$this->set_current_user( $u );
+
+		$u_profile = new BP_XProfile_Data_Template(
+			$r['user_id'],
+			$r['profile_group_id'],
+			$r['hide_empty_groups'],
+			$r['fetch_fields'],
+			$r['fetch_field_data'],
+			$r['exclude_groups'],
+			$r['exclude_fields'],
+			$r['hide_empty_fields'],
+			$r['fetch_visibility_level'],
+			$r['update_meta_cache']
+		);
+
+		$this->assertEquals( 2, $u_profile->group_count );
+		$this->assertEqualSets( array( $g1, $g2 ), array_map( 'intval', wp_list_pluck( $u_profile->groups, 'id' ) ) );
+
+		$g_fields = wp_list_pluck( $u_profile->groups, 'fields' );
+		$u_fields = array();
+
+		foreach( $g_fields as $gf ) {
+			$u_fields = array_merge( $u_fields, $gf );
+		}
+
+		$admin_only = wp_filter_object_list( $u_fields, array( 'id' => $fields[2] ), 'and', 'visibility_level' );
+		$admin_only = array_values( $admin_only );
+
+		$this->assertSame( 'adminsonly', $admin_only[0] );
+
+		// Restore current user
+		$this->set_current_user( $old_user );
+
+		/** Fetch empty field *********************************************************/
+
+		xprofile_set_field_visibility_level( $fields[2], $u, 'public' );
+
+		// Set xprofile args
+		$r = $this->xprofile_get_args( array(
+			'user_id'                => $u,
+			'hide_empty_fields'      => false,
+		) );
+
+		$u_profile = new BP_XProfile_Data_Template(
+			$r['user_id'],
+			$r['profile_group_id'],
+			$r['hide_empty_groups'],
+			$r['fetch_fields'],
+			$r['fetch_field_data'],
+			$r['exclude_groups'],
+			$r['exclude_fields'],
+			$r['hide_empty_fields'],
+			$r['fetch_visibility_level'],
+			$r['update_meta_cache']
+		);
+
+		$this->assertEquals( 2, $u_profile->group_count );
+
+		$g_fields = wp_list_pluck( $u_profile->groups, 'fields' );
+		$u_fields = array();
+
+		foreach( $g_fields as $gf ) {
+			$u_fields = array_merge( $u_fields, $gf );
+		}
+
+		$this->assertTrue( 3 == count( $u_fields ) );
+
+		$empty_field = wp_filter_object_list( $u_fields, array( 'id' => $fields[1] ), 'and', 'data' );
+		$empty_field = array_values( $empty_field );
+
+		$this->assertEmpty( $empty_field[0]->value );
+
+		/** next_group() **************************************************************/
+
+		xprofile_set_field_data( $fields[1], $u, $fvalues[1] );
+
+		// Set xprofile args
+		$r = $this->xprofile_get_args( array(
+			'user_id'          => $u,
+			'profile_group_id' => $g1
+		) );
+
+		$u_profile = new BP_XProfile_Data_Template(
+			$r['user_id'],
+			$r['profile_group_id'],
+			$r['hide_empty_groups'],
+			$r['fetch_fields'],
+			$r['fetch_field_data'],
+			$r['exclude_groups'],
+			$r['exclude_fields'],
+			$r['hide_empty_fields'],
+			$r['fetch_visibility_level'],
+			$r['update_meta_cache']
+		);
+
+		$this->assertEquals( 1, $u_profile->group_count );
+
+		$u_profile->next_group();
+
+		$this->assertEqualSets( array( $fields[0], $fields[1] ), array_map( 'intval', wp_list_pluck( $u_profile->group->fields, 'id' ) ) );
+		$this->assertTrue( 2 == $u_profile->field_count );
+	}
+}
diff --git tests/phpunit/testcases/xprofile/template.php tests/phpunit/testcases/xprofile/template.php
index e69de29..21b4a5d 100644
--- tests/phpunit/testcases/xprofile/template.php
+++ tests/phpunit/testcases/xprofile/template.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * @group xprofile
+ * @group bp_has_profile
+ */
+class BP_Tests_xProfile_Template extends BP_UnitTestCase {
+	protected $groups = array();
+	protected $fields = array();
+
+	public function setUp() {
+		parent::setUp();
+
+		$this->groups = array(
+			$this->factory->xprofile_group->create(),
+			$this->factory->xprofile_group->create(),
+		);
+
+		$this->fields = array(
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $this->groups[0],
+			) ),
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $this->groups[1],
+				'is_required'    => true,
+			) ),
+			$this->factory->xprofile_field->create( array(
+				'type' => 'textbox',
+				'field_group_id' => $this->groups[1],
+			) ),
+		);
+	}
+
+	public function tearDown() {
+		parent::tearDown();
+
+		$this->groups = array();
+		$this->fields = array();
+	}
+
+	/**
+	 * @group bp_get_field_css_class
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_field_css_class() {
+		$u = $this->factory->user->create();
+		$expected = $classes = array();
+
+		foreach ( $this->fields as $k => $f ) {
+			$d = false;
+
+			$d = xprofile_get_field( $f );
+			$classes[ $f ] = array(
+				'id'          => 'field_' . $d->id,
+				'name'        => 'field_' . sanitize_title( $d->name ),
+				'is_required' => 'optional-field',
+				'visibility'  => 'visibility-public',
+				'alt'         => 'alt',
+				'type'        => 'field_type_' . sanitize_title( $d->type ),
+			);
+
+			if ( ! empty( $d->is_required ) ) {
+				$classes[ $f ]['is_required'] = 'required-field';
+			}
+
+			if ( ( $k - 1 ) % 2 != 1 ) {
+				unset( $classes[ $f ]['alt'] );
+			}
+
+			$expected[] = ' class="' . implode( ' ', $classes[ $f ] ) . '"';
+		}
+
+		global $profile_template;
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+			'hide_empty_fields' => false,
+		) );
+
+		$shouldbe = array();
+
+		while ( bp_profile_groups() ) {
+			bp_the_profile_group();
+
+			bp_profile_group_has_fields();
+
+			while ( bp_profile_fields() ) {
+				bp_the_profile_field();
+
+				$shouldbe[] = bp_get_field_css_class();
+			}
+		}
+
+		$this->assertSame( $expected, $shouldbe );
+	}
+
+	/**
+	 * @group bp_get_the_profile_field_ids
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_the_profile_field_ids() {
+		$u = $this->factory->user->create();
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+			'hide_empty_fields' => false,
+		) );
+
+		$shouldbe = explode( ',', bp_get_the_profile_field_ids() );
+
+		$this->assertSame( $this->fields, array_map( 'intval', $shouldbe ) );
+	}
+
+	/**
+	 * @group bp_get_the_profile_group_id
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_the_profile_group_id() {
+		$u = $this->factory->user->create();
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+			'hide_empty_fields' => false,
+		) );
+
+		$shouldbe = array();
+
+		while ( bp_profile_groups() ) {
+			bp_the_profile_group();
+
+			$shouldbe[] = bp_get_the_profile_group_id();
+		}
+
+		$this->assertSame( $this->groups, array_map( 'intval', $shouldbe ) );
+	}
+
+	/**
+	 * @group bp_get_the_profile_field_id
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_the_profile_field_id() {
+		$u = $this->factory->user->create();
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+			'hide_empty_fields' => false,
+		) );
+
+		$shouldbe = array();
+
+		while ( bp_profile_groups() ) {
+			bp_the_profile_group();
+
+			bp_profile_group_has_fields();
+
+			while ( bp_profile_fields() ) {
+				bp_the_profile_field();
+
+				$shouldbe[] = bp_get_the_profile_field_id();
+			}
+		}
+
+		$this->assertSame( $this->fields, array_map( 'intval', $shouldbe ) );
+	}
+
+	/**
+	 * @group bp_get_the_profile_group_field_ids
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_the_profile_group_field_ids() {
+		$u = $this->factory->user->create();
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+			'hide_empty_fields' => false,
+		) );
+
+		$expected = array( (string) $this->fields[0], $this->fields[1] . ',' . $this->fields[2] );
+		$shouldbe = array();
+
+		while ( bp_profile_groups() ) {
+			bp_the_profile_group();
+
+			$shouldbe[] = bp_get_the_profile_group_field_ids();
+		}
+
+		$this->assertSame( $expected, $shouldbe );
+	}
+
+	/**
+	 * @group bp_get_the_profile_field_value
+	 * @group bp_has_profile
+	 */
+	public function test_bp_get_the_profile_field_value() {
+		$u = $this->factory->user->create();
+		$fdata = array( 'foo bar', 'bar foo', 'taz zat' );
+		$expected = array();
+
+		foreach ( $this->fields as $k => $f ) {
+			xprofile_set_field_data( $f, $u, $fdata[ $k ] );
+
+			$expected[] = apply_filters( 'bp_get_the_profile_field_value', $fdata[ $k ], 'textbox', $f );
+		}
+
+		bp_has_profile( array(
+			'user_id'           => $u,
+			'exclude_groups'    => 1,  // exclude the base group
+		) );
+
+		$shouldbe = array();
+		$has_data = 0;
+
+		while ( bp_profile_groups() ) {
+			bp_the_profile_group();
+
+			bp_profile_group_has_fields();
+
+			while ( bp_profile_fields() ) {
+				bp_the_profile_field();
+
+				if ( bp_field_has_data() ) {
+					$has_data += 1;
+				}
+
+				$shouldbe[] = bp_get_the_profile_field_value();
+			}
+		}
+
+		$this->assertTrue( 3 == $has_data );
+		$this->assertSame( $expected, $shouldbe );
+	}
+}
